Reputation: 7459
referring the question Saving bidirectional ManyToMany i want to obtain exacltly what accepted answer explain as incorrect:
A a1 = new A();
A a2 = new A();
B b = new B();
a1.getB().add(b);
b.getA().add(a2);
If this state could be persisted, you would end up with the following entries in the join table:
a1_id, b_id
a2_id, b_id
But upon loading, how would JPA know that you intended to only let b know about a2 and not a1 ? and what about a2 that should not know about b ?
in my case it is correct that b knows about a1 and a2 in EVERY situation.
think about parent-child relation:
and for me it is erroneous to define only one direction:
to obtain what accepted answer is explaining i think i need TWO join tables:
a_has_b:
a1_id, b_id
b_has_a
b_id, a2_id
am i wrong??
i think that implementing
...
public void addB(A a)
{
getA().add(a);
a.getB().add(this);
}
is a really ugly hack...
and using two unidirectional OneToMany on both sides does not work in EclipseLink 2.2.0 (not so sure, i'm currently trying)
thx :)
Upvotes: 3
Views: 4724
Reputation: 7459
using two unidirectional OneToMany will do the trick:
@Entity
@Table
public class A implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id", nullable = false)
private Long id;
@OneToMany
@JoinTable(name="a_b",
joinColumns = @JoinColumn(name = "a_id", nullable = false),
inverseJoinColumns = @JoinColumn(name = "b_id", nullable = false)
)
private List<B> bList = new ArrayList<B>();
}
---------------------------------------------------------------------------------
@Entity
@Table
public class B implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id", nullable = false)
private Long id;
@OneToMany
@JoinTable(name="a_b",
joinColumns = @JoinColumn(name = "b_id", nullable = false),
inverseJoinColumns = @JoinColumn(name = "a_id", nullable = false)
)
private List<A> aList = new ArrayList<A>();
}
refreshing entity will fill list
Upvotes: 3
Reputation: 18379
Using,
public void addA(A a)
{
getA().add(a);
a.getB().add(this);
}
Is not a hack. This is good object-oriented programming. In any Java model, ignoring persistence, if you have a bi-directional relationship, you must add to both sides to correct related anything. Your code should not change just because you are, or are not, using persistence.
If you want to maintain the relationships separately, you need to have two different join tables. If you want a single ManyToMany relationship (it seems you do), then you must use @ManyToMany and set the mappedBy on one side.
See, http://en.wikibooks.org/wiki/Java_Persistence/ManyToMany
Upvotes: 3
Reputation: 21
I faced the problem on updating via the non-owning side. I put @ManyToMany and @JoinTable on both side (no mappedBy). It is working nicely. I am using Hibernate 4.1.10.Final. As per wiki documents, it is not right. Confused ??
Upvotes: 1