TER
TER

Reputation: 57

JPA Annotations and mappedBy

I am working on java application and using JPA to interact with the database, I have two important questions:

  1. I want to make a bi-directional link between two classes since I need to access the data on both sides. Let's take the case of two classes A and B with A *-1 B (as UML diagram, A has an unique B and B has several A ..).

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?

  1. 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)? For example in the case of the cardinality 1-* we have no choice, the mappedBy should be in the side of OneToMany and in this case:

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

Answers (3)

NickJI
NickJI

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

Shahzeb
Shahzeb

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

Chris K
Chris K

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).
  • If mappedBy is on the wrong side, you should see an exception.

Upvotes: 1

Related Questions