Most often we can think of
a pair representing 2 sides of a relationship. As such @OneToMany has the
side of the relationship and @ManyToOne has the
"one" side of the relationship.
mappedBy attribute should be defined in most @OneToMany.
The mappedBy attribute effectively refers to the other side of the relationship.
Example: Customer has many Contacts
@Entity public class Customer ... // mappedBy referring to the other side of this relationship @OneToMany(mappedBy="customer") List<Contact> contacts; ...
On the other side of the relationship in the Contact entity bean we define the
@ManyToOne property that the
mappedBy refers to.
@Entity public class Contact ... // the customer property referred to by @OneToMany(mappedBy="customer") @ManyToOne(optional=false) Customer customer; ...
When we map both sides of the relationship with a
pair we can describe this as a bi-directional relationship. The relationship can be viewed, navigated
and loaded from both directions.
There are no restrictions or limitations when we have a bi-directional relationship.
Not mapping the @OneToMany
The reason we might choose to not map the
@OneToMany side of a relationship is
when the cardinality is high (say thousands) and we deem that we never want to
allow the application to navigate the relationship in that direction as doing so naively
might load too many of objects.
For example if a Customer had 1 million Orders and we naively navigated from that Customer to
all their orders we could load 1 millions Order instances into memory which is generally something
we don't want to do. In this case we could use
filterMany on a Customer query
to filter the orders for each customer (e.g. orders created in the last week). Alternatively we can
load the graph in the other direction (From Order to Customer).
Omitting a @OneToMany effectively means we can't navigate or load the relationship from that direction and instead it forces the application to always use the other direction (to build object graphs).
Not mapping the @ManyToOne
When we do not map the @ManyToOne this adds a restriction and implies an
For example take the case of
Order having many
OrderDetail. When we don't map
the @ManyToOne side in OrderDetail:
Order has details:
@Entity @Table(name = "orders") public class Order ... // we MUST have cascade persist here for this // unidirectional case (no @ManyToOne) @OneToMany(cascade = CascadeType.ALL) List<OrderDetail> details; ...
OrderDetail has no matching @ManyToOne:
@Entity public class OrderDetail ... // Does not have - @ManyToOne(optional = false) Order order;
This effectively adds the restriction that to insert new OrderDetails we must
cascade persist from Order to do so. That is, the @ManyToOne effectively represents
the foreign key column that is on the underlying table for OrderDetail and to populate
that foreign key column
we must use cascade persist from Order.
This also implies that the foreign key value can never change and hence we can view
this conceptually as an
In this example each OrderDetail is 'owned' by an Order.
Personally I always map the @ManyToOne