Java Reference
In-Depth Information
As the listing shows, an eager fetch means that the most natural way of retrieving the
Item
entity would be through a single
SELECT
statement using a
JOIN
between the
ITEMS
and
SELLERS
tables. It's important to note the fact that the
JOIN
will result in a single
row, containing columns from both the
SELLERS
and
ITEMS
tables. In terms of database
performance, this is more efficient than issuing one
SELECT
to retrieve the
Item
and is-
suing a separate
SELECT
to retrieve the related
Seller
. This is exactly what would have
happened in a case of lazy fetching, and the second
SELECT
for retrieving the
Seller
will be issued when the
Item
's
seller
property is first accessed. Pretty much the same
thing applies to the
@OneToOne
annotation, so the default for it is also eager loading.
More specifically, the
JOIN
to implement the relationship would result in a fairly efficient
single combined row in all cases.
Lazy versus eager loading of related entities
In contrast, the
@OneToMany
and
@ManyToMany
annotations are defaulted to lazy load-
ing. The critical difference is that for both of these relationship types, more than one entity
is matched to the retrieved entity. Think about
Category
entities related to a retrieved
Item
, for example.
JOIN
s implementing eagerly loaded one-to-many and many-to-many
relationships usually return more than one row. In particular, a row is returned for every
related entity matched.
The problem becomes particularly obvious when you consider what happens when multiple
Item
entities are retrieved at one time (for example, as the result of a JPQL query, dis-
cussed in the next chapter). (
N
1
+
N
2
+ ... +
N
x
) rows would be returned, where
N
i
is the
number of related
Category
entities for the ith
Item
record. For nontrivial numbers of
N
and
i
, the retrieved result set could be quite large, potentially causing significant database
performance issues. This is why JPA makes the conservative assumption of defaulting to
lazy loading for
@OneToMany
and
@ManyToMany
annotations.
Table 10.2
lists the default fetch behavior for each type of relationship annotation.
Table 10.2. Behavior of loading an associated entity is different for each kind of association by default. You can
change the loading behavior by specifying the
fetch
element with the relationship.
Relationship type
Default fetch behavior
Number of entities retrieved
One-to-one
EAGER
Single entity retrieved
One-to-many
LAZY
Collection of entities retrieved