In the example section of the @OneToMany
JPA annotation reference:
Example 1-59 @OneToMany – Customer Class With Generics
@Entity
public class Customer implements Serializable {
...
@OneToMany(cascade=ALL, mappedBy="customer")
public Set<Order> getOrders() {
return orders;
}
...
}
Example 1-60 @ManyToOne – Order Class With Generics
@Entity
public class Order implements Serializable {
...
@ManyToOne
@JoinColumn(name="CUST_ID", nullable=false)
public Customer getCustomer() {
return customer;
}
...
}
It seems to me that the Customer
entity is the owner of the association. However, in the explanation for the mappedBy
attribute in the same document, it is written that:
if the relationship is bidirectional,
then set the mappedBy element on the
inverse (non-owning) side of the
association to the name of the field
or property that owns the relationship
as Example 1-60 shows.
However, if I am not wrong, it looks like in the example, the mappedBy
is actually specified on the owning side of the association, rather than the non-owning side.
So my question is basically:
-
In a bidirectional (one-to-many/many-to-one) association, which of the entities is the owner? How can we designate the One side as the owner? How can we designate the Many side as the owner?
-
What is meant by "the inverse side of the association"? How can we designate the One side as the inverse? How can we designate the Many side as the inverse?
Best Answer
To understand this, you must take a step back. In OO, the customer owns the orders (orders are a list in the customer object). There can't be an order without a customer. So the customer seems to be the owner of the orders.
But in the SQL world, one item will actually contain a pointer to the other. Since there is 1 customer for N orders, each order contains a foreign key to the customer it belongs to. This is the "connection" and this means the order "owns" (or literally contains) the connection (information). This is exactly the opposite from the OO/model world.
This may help to understand:
The inverse side is the OO "owner" of the object, in this case the customer. The customer has no columns in the table to store the orders, so you must tell it where in the order table it can save this data (which happens via
mappedBy
).Another common example are trees with nodes which can be both parents and children. In this case, the two fields are used in one class:
This explains for the "foreign key" many-to-one design works. There is a second approach which uses another table to maintain the relations. That means, for our first example, you have three tables: The one with customers, the one with orders and a two-column table with pairs of primary keys (customerPK, orderPK).
This approach is more flexible than the one above (it can easily handle one-to-one, many-to-one, one-to-many and even many-to-many). The price is that
That's why I rarely recommend this approach.