674 words

Broken @ManyToOne reference

#1
2013-03-18 14:27

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

tsichevski
tsichevski's picture
Joined on 2013-03-14
User Post #3
#2
2013-03-18 14:30

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)
support
support's picture
Joined on 2010-05-03
User Post #1,451
#3
2013-03-25 09:40

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

tsichevski
tsichevski's picture
Joined on 2013-03-14
User Post #8
#4
2013-03-25 11:35

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)
support
support's picture
Joined on 2010-05-03
User Post #1,463
#5
2013-03-25 13:38

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

tsichevski
tsichevski's picture
Joined on 2013-03-14
User Post #9
#6
2013-03-25 14:59

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)
support
support's picture
Joined on 2010-05-03
User Post #1,464
#7
2013-03-25 18:54

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
tsichevski
tsichevski's picture
Joined on 2013-03-14
User Post #10
#8
2013-03-26 21:06

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)
support
support's picture
Joined on 2010-05-03
User Post #1,467
#9
2013-03-26 21:31

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)
support
support's picture
Joined on 2010-05-03
User Post #1,468
#10
2013-03-27 21:25

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

tsichevski
tsichevski's picture
Joined on 2013-03-14
User Post #11
#11
2013-03-27 23:42

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)
support
support's picture
Joined on 2010-05-03
User Post #1,471
#12
2013-03-28 08:03

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

tsichevski
tsichevski's picture
Joined on 2013-03-14
User Post #12
#13
2013-03-28 10:14

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)
support
support's picture
Joined on 2010-05-03
User Post #1,472

Post Reply

Please read carefully the posting instructions - before posting to the ObjectDB website.

  • You may have to disable pop up blocking in order to use the toolbar (e.g. in Chrome).
  • Use ctrl + right click to open the browser context menu in the editing area (e.g. for using a browser spell checker).
  • To insert formatted lines (e.g. Java code, stack trace) - select a style in the toolbar and then insert the text in the new created block.
  • Avoid overflow of published source code examples by breaking long lines.
  • You may mark in paragraph code words (e.g. class names) with the code style (can be applied by ctrl + D).
  • Long stack traces (> 50 lines) and complex source examples (> 100 lines) should be posted as attachments.
Attachments:
Maximum file size: 32 MB
Cancel