Broken @ManyToOne reference

#1

Hi,

I have objects of type A belonging to objects of type B, defined as follows:

@MappedSuperclass public abstract class A {
  @Id
  @ManyToOne(fetch = FetchType.EAGER, cascade=CascadeType.ALL, optional=false)
  private B b;

  @Id
  @Column(length = 36)
  private String stringId;
}

@MappedSuperclass public abstract class B {
  @Id
  private String name;
}

Both objects store with no error, but after they are retrived, the 'b' variable in all A objects is always null.

Regards,

Vladimir

PS: the same configuration works well with Hibernate

#2

This is an unexpected behavior, B instances should be fetched eagerly in this case.

Please follow the posting instructions and provide a test case that demonstrates the problem.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#3

You'll find a tiny Eclipse project attached. Please run the main() in the testobjectdb.Main class. In this method:

# in a transaction, two instances are created and persisted: a Parent and a Child, the Child instance references the Parent instance in the prn field, which is a part of @Id of the Child Entity.

# in a fresh EntityManager the Child instance is retrieved. Now it has null in the prn field.

The output shall look like:

Parent reference written: testobjectdb.Parent@e425743
Parent reference read back: null

Regards,

Vladimir

#4

The model in the test is not exactly the one that was initially described in #1.

It is unclear why is the @Id annotation used in more than one level in the child hierarchy. This is invalid in JPA and it is not supported by ObjectDB.

After commenting the @Id annotation at ChildSuper:

package testobjectdb;

import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;

@MappedSuperclass
public abstract class ChildsSuper {
 
//  @Id
  @ManyToOne(fetch = FetchType.EAGER)
  public AbstractParent prn;
}

the output of the tests seems as expected:

Parent reference written: testobjectdb.Parent@76a9b9c
Parent reference read back: testobjectdb.Parent@6ab30913

 

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#5

Hi support,

it is a pity to hear it. You are probably right, seems JPA spec says nothing whether such situations are allowed or forbidden.

Unfortunately, in my schema the child id must be composed from the parent Id and the child subkey. And I have multiple child subtypes in which child subkeys are of different nature. At the moment, Hibernate serves me well, and in the future I will have to redesign my scheme significally to make it objectdb/JPA-compatible :-(

Thanks,

Vladimir

#6

If Hibernate allows ID inheritance then maybe ObjectDB should allow it as well.

There is no technical difficulty here, just the question what is expected by JPA.

Anyway, please try build 2.4.7_08.

Your test should pass with ID set across the hierarchy, but the retrieval should be adjusted:

    // Child child = em.find(Child.class, Main.CHILD_ID);
    Child child = em.createQuery("SELECT  e FROM Child e", Child.class).getSingleResult();

because Main.CHILD_ID is only part of the primary key now.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#7

Hi support,

 

just tried the fixed version. Two notes:

1. For a composite key an instance of the target class may be used. At least it works with Hibernate:

Child template = new Child();
template.rn = Main.CHILD_ID;
template.prn = parent;
Child child = em.find(Child.class, template);

It does not work with ObjectDB though :-(

2. The instance of some different class is now referenced by the child returned:

Parent reference written: testobjectdb.Parent@20873723
Parent reference read back: objectdb.testobjectdb.AbstractParent@1bd7b222

This class is not compatible with the expected Parent:

System.out.println(child.prn instanceof AbstractParent); // true
System.out.println(child.prn instanceof Parent); // false
#8

Point 2 is indeed a bug. Build 2.4.7_09 fixes it.

Regarding point 1, this is not valid in JPA and may be a Hibernate extension.

You should use an ID class to represent composite primary keys in a portable JPA way.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#9

Apparently implementing that Hibernate extension (of using find with an entity that contains the PK) required adding only 2 lines of codes to ObjectDB. Please try build 2.4.7_10.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#10

Hi support,

thank you for fixing previous problems. Here is a new one. Using the same class structure as in my previous posts, I got:

EntityManager em = ...;

System.out.println("Is single ID attribute: " + em.getMetamodel().entity(Child.class).hasSingleIdAttribute());

prints true, which is not the case since the Child class ID is a composite.

 

Regards,

Vladimir

#11

Thank you for this report.

Adjustments are needed to support the new partial primary key feature.

It should work with build 2.4.7_12.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)
#12

Wow, eventually is works! Seems I caused 5 new releases in 3 days :-) To be continued...

#13

It was relatively easy to make these changes to support Hibernate behavior (which seems to extend basic JPA). However, you would probably need to change some parts in your application as well, in order to port it to ObjectDB.

ObjectDB Support
ObjectDB - Fast Object Database for Java (JPA/JDO)

Post Reply

To post a reply and/or subscribe to update notifications - please login