How do the Query/Result caches and the L1 cache work together?


I've been encountering something I don't understand with the Query caches and the L1 cache.   I've tried reading the DN docs a few times, but I am still confused by the results I am seeing.

My persistence unit uses the default cache configuration, with no specific settings for the caches identified.  To my understanding then, the queryCache and the queryResult cache should be using soft references with unlimited size.  However, when I add profiling to my DB connection, I see the exact same query being executed multiple times.  For example, I will see the following query executed 4 times in a row:

exec sp_executesql N'SELECT ''izo.model.ActivePerson'' AS DN_TYPE FROM ACTIVEPERSON A0 WHERE A0.TYP = ''izo.model.ActivePerson'' AND A0.ID = @P0 UNION SELECT ''izo.model.Athlete'' AS DN_TYPE FROM ATHLETE A0 WHERE A0.TYP = ''izo.model.Athlete'' AND A0.ID = @P1 UNION SELECT ''izo.model.AthleteAgent'' AS DN_TYPE FROM ATHLETEAGENT A0 WHERE A0.TYP = ''izo.model.AthleteAgent'' AND A0.ID = @P2',N'@P0 bigint,@P1 bigint,@P2 bigint',4319,4319,4319

Normally, I would have expect this query to be added to the query cache, and the result to be in the queryResult cache.  Similarly, I would also expect the retrieved object(s) to be added to the L1 cache, and used for subsequent retrievals.

1) Is the L1 cache only used if retrieving objects by Identity?
2) How does the query cache work?  What makes a query cacheable?  
3) Why would the query/result cache not be responding instead of re-querying the DB multiple times?




An L1 cache is an object cache, as defined by the JDO spec. You have an "id" you get the equivalent persistable object. It is used anywhere a persistable object is accessible, and that includes queries if the queries returns a persistable object. The log tells you where objects come from.

Query caching (in DataNucleus, not defined by the JDO spec) is a 3 level process ... generic compilation, datastore compilation, results. Compilations are always cached. Results are only cached when you tell it to cache them, via the query extension datanucleus.query.results.cached
It would make no sense to cache the results of every query for all types of software that use DataNucleus, hence it is off by default.