EAGER LOADING OF RELATIONSHIPS
Regardless of whether the relationship is fetched lazily or eagerly, the loop here will execute
33,408 SELECT statements to retrieve the stock options (as the last section mentioned, a JOIN will
not be used by default).
The difference between eagerly and lazily loading the relationship in this situation applies to
when those SQL statements are executed. If the relationship is annotated to load eagerly, when the
query is executed the result set is processed immediately (within the call to the getResultList()
method). The JPA framework looks at every entity returned in that call and executes an SQL
statement to retrieve their related entities. All these SQL statements occur at SQL Call Site 1—in
the eager relationship case, no SQL statements are executed at SQL Call Site 2.
If the relationship is annotated to load lazily, then only the stock prices are loaded at SQL Call
Site 1 (using the named query). The option prices for individual stocks are loaded when the rela-
tionship traversal occurs at SQL Call Site 2. That loop is executed 33,408 times, resulting in the
33,408 SQL calls.
Regardless of when the SQL is issued, though, the number of SQL statements remains the
same—assuming that all the data is actually used in the lazy-loading example.
Join fetch and caching
As discussed in the previous section, the query could be written to explicitly use a JOIN
@NamedQuery ( name = "findAll" ,
query = "SELECT s FROM StockPriceEagerLazyImpl s " +
"JOIN FETCH s.optionsPrices ORDER BY s.id.symbol" )
Table 11-5. Seconds required to read data for 128 stocks ( JOIN query)
61.9 seconds (33,409 SQL calls) 3.2 seconds (1 SQL call)
17.9 seconds (1 SQL call)
11.4 seconds (1 SQL call)
Join fetch with query cache 17.9 seconds (1 SQL call)
1.1 seconds (0 SQL call)