EclipseLink/UserGuide/JPA/Basic JPA Development/Caching/Query Options
|Mailing List • Forums • IRC • mattermost|
|Open • Help Wanted • Bug Day|
Query Cache Options and In-memory Querying
JPA defines standard query hints for configuring how a query interacts with the shared persistence unit cache (L2). EclipseLink also provides some additional query hints for configuring the cache usage.
Entities can be accessed through JPA using either find() or queries. find() will first check the persistence context cache (L1) for the Id, if the object is not found it will check the shared persistence unit cache (L2), if the object is still not found it will access the database. By default all queries will access the database, unless querying by Id or by cache indexed fields. Once the query retrieves the rows from the database, it will resolve each row with the cache. If the object is already in the cache, then the row will be discarded, and the object will be used. If the object is not in the shared cache, then it will be built from the row and put into the shared cache. A copy will also be put in the persistence context cache and returned as the query result.
This is the general process, but it differs if the transaction is dirty. If the transaction is diry then the shared persistence unit cache will be ignored and objects will be built directly into the persistence context cache.
A transaction is considered dirty in the following circumstances:
- A flush() has written changes to the database.
- A pessimistic lock query has been executed.
- An update or delete query has been executed.
- A native SQL query has been executed.
- This persistence unit property "eclipselink.transaction.join-existing" is used.
- The JDBC connection has been unwrapped from the EntityManager.
- The UnitOfWork API beginEarlyTransaction has been called.
Entities can also be configured to be isolated, or non cacheable, in which case they will never be placed in the shared cache (see Shared, Isolated, Protected, Weak and Read-only Cache).
The JPA query hints allow for queries or the find() operation to bypass, or refresh the shared cache. The EclipseLink query hints allow for queries or the find() operation to query the cache, conform with the persistence context, bypass both the shared and persistence context caches, or return read-only objects.
JPA Cache Query Hints
JPA 2.0 defines the following query hints to configure a queries interaction with the shared cache. JPA cache query hints can be set on named or dynamic queries, or set in the properties map passed to the find() operation.
|javax.persistence.cache.retrieveMode||Configure how the shared cache is accessed.
Valid values are defined in CacheRetrieveMode enum:
|javax.persistence.cache.storeMode||Configure how the shared cache is modified.
Valid values are defined in CacheStoreMode enum:
Refresh query hint example
Query query = em.createQuery("Select e from Employee e where e.address.city = :city"); query.setHint("javax.persistence.cache.storeMode", "REFRESH"); query.setParameter("city", "Ottawa"); List<Employee> employees = query.getResultList();
EclipseLink Cache Query Hints
EclipseLink defines the following query hints to configure a queries interaction with the shared cache:
|eclipselink.refresh||Configure the query to refresh the objects in both the shared cache and/or the persistence context cache with the database row data.||false||Optional|
|eclipselink.refresh.cascade||Configures how refreshing is cascaded to relationships, if the query has been configured to refresh.
Valid values are defined in CascadePolicy:
|eclipselink.cache-usage||Configures in-memory querying and cache usage.
Valid values are defined in CacheUsage:
|eclipselink.maintain-cache/tt></td>||Configure the query to bypass both the shared and the persistence context cache. This returns detached objects.
Depending on the cascade mode, the detached objects relationships may be managed or also detached. </td>
|eclipselink.read-only/tt></td>||Configure the query to return read-only objects, and bypass the persistence context cache.
Read-only objects are from the shared cache (depending on the cache isolated), and must not be modified. </td>
In-memory query example
Query query = em.createQuery("Select e from Employee e where e.firstName like :firstName and e.lastName like :lastName"); query.setHint("eclipselink.cache-usage", "CheckCacheThenDatabase"); query.setParameter("firstName", "Bob"); query.setParameter("lastName", "Smith"); List<Employee> employees = query.getResultList();