JPA doesn't currently define a mechanism for caching of queries. DataNucleus provides
3 levels of caching

Generic Compilation : when a query is compiled it is
initially compiled
generically
into expression trees. This generic compilation
is independent of the datastore in use, so can be used for other datastores.
This can be cached.

Datastore Compilation : after a query is compiled
into expression trees (above) it is then converted into the native language of the
datastore in use. For example with RDBMS, it is converted into SQL.
This can be cached

Results : when a query is run and returns objects of the candidate
type, you can cache the identities of the result objects.

This cache is by default set to
weak
, meaning that the generic query compilation
is cached using weak references. This is set using the persistence property
datanucleus.cache.queryCompilation.type
. You can also set it to
strong
meaning that strong references are used, or
soft
meaning that soft references
are used, or finally to
none
meaning that there is no caching of generic query
compilation information

You can turn caching on/off (default = on) on a query-by-query basis by specifying the
query extension
datanucleus.query.compilation.cached
as true/false.

This cache is by default set to
weak
, meaning that the datastore query compilation
is cached using weak references. This is set using the persistence property
datanucleus.cache.queryCompilationDatastore.type
. You can also set it to
strong
meaning that strong references are used, or
soft
meaning that soft references
are used, or finally to
none
meaning that there is no caching of datastore-specific
query compilation information

You can turn caching on/off (default = on) on a query-by-query basis by specifying the
query extension
datanucleus.query.compilation.cached
as true/false.
As a finer degree of control, where cached results are used, you can omit the validation
of object existence in the datastore by setting the query extension
datanucleus.query.resultCache.validateObjects
.

This cache is by default set to
weak
, meaning that the datastore query results
are cached using weak references. This is set using the persistence property
datanucleus.cache.queryResult.type
. You can also set it to
strong
meaning that strong references are used, or
soft
meaning that soft references
are used, or finally to
none
meaning that there is no caching of query results
information. You can also specify
datanucleus.cache.queryResult.cacheName
to define
the name of the cache used for the query results cache.

You can turn caching on/off (default = off) on a query-by-query basis by specifying the
query extension
datanucleus.query.results.cached
as true/false.

Obviously with a cache of query results, you don't necessarily want to retain this cached
over a long period. In this situation you can evict results from the cache like this.