OTHER MECHANISMS FOR A JOIN FETCH
Many JPA providers allow a join fetch to be specified by setting query hints on a query. For ex-
ample, in EclipseLink, this code will produce a JOIN query:
Query q = em . createQuery ( "SELECT s FROM StockOptionImpl s" );
q . setQueryHint ( "eclipselink.join-fetch" , "s.optionsPrices" );
Some JPA providers also have a special @JoinFetch annotation that can be used on the relation-
The exact SQL will differ among JPA providers (this example is from EclipseLink), but this
is the general process.
Join fetching is valid for entity relationships regardless of whether they are annotated as
eager or lazy. If the join is issued on a lazy relationship, the lazily annotated entities that sat-
isfy the query are still retrieved from the database, and if those entities are later used, no ad-
ditional trip to the database is required.
When all the data returned by a query using a join fetch will be used, then the join fetch often
provides a big improvement in performance. However, a join fetch also interacts with the
JPA cache in unexpected ways. An example of that is shown in the section on caching; be
sure you understand those ramifications before writing custom queries using join fetch.
Batching and queries
JPA queries are handled like a JDBC query yielding a result set: the JPA implementation has
the option of getting all the results at once, getting the results one at a time as the application
iterates over the query results, or getting a few results at a time (analogous to how the fetch
size worked for JDBC).
There is no standard way to control this, but JPA vendors have proprietary mechanisms to set
the fetch size. In EclipseLink, a hint on the query specifies the fetch size:
q . setHint ( "eclipselink.JDBC_FETCH_SIZE" , "100000" );
Hibernate offers a custom @BatchSize annotation instead.