Java Reference
In-Depth Information
Relationship type
Default fetch behavior
Number of entities retrieved
Many-to-one
EAGER
Single entity retrieved
Many-to-many
LAZY
Collection of entities retrieved
The relationship defaults aren't right for all circumstances, however. Although the eager
fetching strategy makes sense for one-to-one and many-to-one relationships under most cir-
cumstances, it's a bad idea in some cases. For example, if an entity contains a large number
of one-to-one and many-to-one relationships, eagerly loading all of them would result in
a large number of
JOIN
s chained together. Executing a relatively large number of
JOIN
s
can be just as bad as loading an (
N
1
+
N
2
+ ... +
N
x
) result set. If this proves to be a perform-
ance problem, some of the relationships should be loaded lazily. Here's an example of ex-
plicitly specifying the fetch mode for a relationship (it happens to be the familiar
Seller
property of the
Item
entity):
@ManyToOne(fetch=FetchType.LAZY)
public Seller getSeller() {
return seller;
}
You shouldn't take the default lazy loading strategy of the
@OneToMany
and
@ManyToMany
annotations for granted. For particularly large data sets, this can result
in a huge number of
SELECT
s being generated against the database. This is known as
the
N
+ 1 problem, where 1 stands for the
SELECT
statement for the originating entity
and
N
stands for the
SELECT
statement that retrieves each related entity. In some cases,
you might discover that you're better off using eager loading even for
@OneToMany
and
@ManyToMany
annotations.
Unfortunately, the choice of fetch modes isn't cut and dried, and it depends on a whole
host of factors, including the database vendor's optimization strategy, database design, data
volume, and application usage patterns. In the real world, ultimately these choices are of-
ten made through trial and error. Luckily, with JPA, performance tuning just means a few
configuration changes here and there as opposed to time-consuming code modifications.
Having discussed entity retrieval, we can now move into the third operation of the CRUD
sequence: updating entities.