Reputation: 57
I am working on java application and using JPA to interact with the database, I have two important questions:
in A:
@ManyToOne
private B attribute;
in B
@OneToMany
private List<A> list;
Is that enough to make the two-way link? or it is mandatory to use the mappedBy?
in B
@OneToMany(mappedBy = "attribute")
private List<A> list;
Knowing the fact that I will not create the class B, and create a List and assign objects, I will do nothing in the side B. I'll just create repeatedly classes A and every time I assign it an B object, so I may have several classes A that have the same affected object B and I want that B automatically updates this link and its list of A.
Upvotes: 3
Views: 1998
Reputation: 566
Is that enough to make the two-way link? or it is mandatory to use the mappedBy?
Not quite. You do need the MappedBy
attribute for bidirectional many-to-one relationships on the inverse side - that is the side that does not have the foreign key, and is always the one side in a many-to-one relationship. You also need joincolumn information on the many side of the relationship.
So in summary:
Many-to-one side – the owning side of the relationship - @JoinColumn information is on this side. This needs to be specified in both uni-directional and bidirectional relationships
One-to-many side – the inverse side – mappedBy Attribute on this side. This needs to be specified if the relationship is bidirectional.
@Entity
public class A ……..
//Owning side of the relationship with the @JoinColumn annotation.
@ManyToOne
// Assume TABLEPK column holds PK of B's table
@JoinColumn (name = "TABLEBPK")
private B attribute;
@Entity
public class B ……
//Inverse side of the relationship with the MappedBy attribute.
@OneToMany(MappedBy = “attribute”)
private List<A> list;
Which brings us to my second question, if the mappedBy is placed on the wrong side, it'll just impact the performance or even worse ?
It won't work. Just put it on the inverse side of the relationship.
Knowing the fact that I will not create the class B, and create a List and assign objects, I will do nothing in the side B. I'll just create repeatedly classes A and every time I assign it an B object, so I may have several classes A that have the same affected object B and I want that B automatically updates this link and its list of A.
In this scenario, you create a class A, with the attribute field populated with an instance of B. Now when you persist A - a new instance - it will contain an instance of B in the attribute field that may or may not be new. We want JPA to persiste A and then navigate accross the relationship and persist B also. If B already exists in the perssitence context then ignore it. Adding CascadeType.PERSIST
will achieve this.
@Entity
public class A ……..
//Owning side of the relationship with the @JoinColumn annotation.
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn (name = "TABLEBPK")
private B attribute;
These guys write really well on this stuff.... "Pro JPA 2 Mastering the Java™ Persistence API" by Mike Keith and Merrick Schnicariol."
Upvotes: 1
Reputation: 4785
Is that enough to make the two-way link? or it is mandatory to use the mappedBy?
For a Bi-directional
relationship it is mandatory .
Which brings us to my second question, if the mappedBy is placed on the wrong side, it'll just impact the performance or even worse ? (data not persisted)?
Worse - It will not work but it will not be silent fail you will see exceptions.
Having said that is simple to understand . It goes with @OneToMany
.
This might help you understanding this more.
Upvotes: 2
Reputation: 1723
mappedBy
should be added to the entity which does not have a foreign key in its table (most likely B
in this case).mappedBy
is on the wrong side, you should see an exception.Upvotes: 1