Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Problem with bidirectional OneToMany relationship
Problem with bidirectional OneToMany relationship [message #630442] Sat, 02 October 2010 15:13 Go to next message
dcarbonne  is currently offline dcarbonne Friend
Messages: 14
Registered: October 2010
Junior Member
Hi,

I'm new to EclipseLink and JPA and have a problem understanding what is wrong with my code. I hope this is the right forum for my question.
I tried to find if it was already asked on the net, but did not succeed.

I want to model a bidirectional OneToMany relationship between two classes A and B:
A (0..1) <--> (0..n)B.

If I annotate A.b with @OneToMany(mappedBy="a"), then the A->B relation table is not generated.
When I move this annotation to the getter (A.getB()), then the relation table is generated.

I should say that if I remove (mappedBy="a"), then there are two mono-directional relationships, and things work as expected.

I'm quite surprised by this behaviour. IIUC JPA specification, annotations must only be used on FIELDS or (exclusive) PROPERTIES. To make things work (as I would like them to), there is a mix of annotations, which seems wrong to me.

I don't understand why initial code does not work, and why modified one works!
What am I doing wrong?
This example seems so close to examples I've read that is is quite frustrating.

The behaviour is he same on Windows and Linux (I use latest Helios, derby and EclipseLink on both systems).

Thanks in advance for your help.

Regards,
Damien Carbonne

Code follows.

tests02/A.java
package test02;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.*;

@Entity
public class A implements Serializable {

   private static final long serialVersionUID = 1L;

   @Id
   private int id;

   @OneToMany(mappedBy = "a") // YThis does not work as expected
   private List<B> b = new ArrayList<B>();

   public A() {
      super();
   }

   public A(int id) {
      this.id = id;
   }

   public int getId() {
      return this.id;
   }

   public void setId(int id) {
      this.id = id;
   }

   public void setB(List<B> b) {
      this.b = b;
   }

// When using this annotation (and commenting the above one), things work as expected (by me)
//   @OneToMany(mappedBy = "a")
   public List<B> getB() {
      return b;
   }   
}



tests02/B.java
package test02;

import java.io.Serializable;
import javax.persistence.*;

@Entity
public class B implements Serializable {

   private static final long serialVersionUID = 1L;

   @Id
   private int id;

   @ManyToOne
   private A a;

   public B() {
      super();
   }

   public B(int id) {
      this.id = id;
   }

   public int getId() {
      return this.id;
   }

   public void setId(int id) {
      this.id = id;
   }

   public A getA() {
      return a;
   }

   public void setA(A a) {
      this.a = a;
   }
}








Re: Problem with bidirectional OneToMany relationship [message #630643 is a reply to message #630442] Mon, 04 October 2010 13:25 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1039
Registered: July 2009
Senior Member
Hello,

As the you mentioned, the JPA specification does not allow mixing annotation access types. When they are mixed as you mentioned, what is happening is that some annotations are being ignored and the defaults for those are being used instead. In the case of your A.b, the default will be a many to many mapping (pretty much the same thing as a uni-directional 1:M mapping), and so a relational table gets generated. When you have the A.b annotated with the mappedby, no relation table is generated because it uses the referenced B.a mapping information.

The B.a ManyToOne is specifying that the B table has a foreign key to A,.

Hope this helps.

best Regards,
Chris
Re: Problem with bidirectional OneToMany relationship [message #630771 is a reply to message #630643] Mon, 04 October 2010 21:28 Go to previous message
dcarbonne  is currently offline dcarbonne Friend
Messages: 14
Registered: October 2010
Junior Member
Thanks for explanations on use of mixed annotations. That part is clear.

However, I still don't understand why the initial code does not work!
Why is the relation table not generated when I use FIELD annotations + TABLE_PER_CLASS inheritance strategy? What should be done so that this combination works?

By the way, what is the real purpose of mappedBy?
All things I have read on bidirectional relationship tell that one must handle consistency between both direction by hand. Is there any check done at the B level to ensure that the relationship is bidirectional, is this a provision for future use, or something else.
More precisely, what does it concretely change to remove all mappedBy?

Best regards,
Damien
Previous Topic:JPQL subquery error
Next Topic:MOXy/JAXB ClassCastException: attempting to cast bundleresource://.../JAXBContext.class to jar:file:
Goto Forum:
  


Current Time: Thu Dec 18 02:24:59 GMT 2014

Powered by FUDForum. Page generated in 0.02130 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software