You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Jean-Paul Le Fèvre <je...@cea.fr> on 2007/08/01 16:06:04 UTC

How the cache works ?

I don't understand how the caching mechanism works in cayenne 1.2 !

My selections are implemented as follows :

      SelectQuery query = new SelectQuery(Simulation.class,
                          ExpressionFactory.matchExp("name", name));
      query.setFetchLimit(1);
      query.setName("SimulationSelection");
      query.setCachePolicy(QueryMetadata.SHARED_CACHE);

      List list = context.performQuery(query);

      if (list == null || list.size() < 1) {
          return null;
      }

      return (Simulation) list.get(0);

A call to this code returns null even when a simulation exists.
More horribly this kind of code returns a wrong object in some cases.
Using LOCAL_CACHE gives the same wrong result.
Setting SHARED_CACHE_REFRESH fixes the problem, but it simply means that
the cache is not used.

Moreover I don't know if there is a way to configure the size of the cache.

As a result I'm wondering whether it is better to implement a cache in
my own application.

Regards,

-- 
___________________________________________________________________

Jean-Paul Le Fèvre  * Mail : LeFevre@fonteny.org


Re: How the cache works ?

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Aug 1, 2007, at 5:06 PM, Jean-Paul Le Fèvre wrote:

> Moreover I don't know if there is a way to configure the size of  
> the cache.

More on that.... IMO until 3.0 query cache (as opposed to individual  
object cache) was fairly immature. Users have very little control  
over its behavior. Some things were easy to fix (like the one I  
mentioned before), but others were not so simple.

In 3.0 caching mechanism is pluggable and I've personally pushed the  
envelope pretty far in customizing it in my own applications. What's  
missing (due to the early alpha status of 3.0) is good documentation  
and Modeler support.

What you can already do is this:

1. Configure Query Cache Policy

DataDomain domain = ..
domain.setQueryCacheFactory(new OSQueryCacheFactory());
// default is "domain.setQueryCacheFactory(new MapQueryCacheFactory());"
// and you can write your own as well..

OSQueryCacheFactory (based on OSCache as the name implies) allows you  
to configure cross-VM notifications, "group" expiration policies,  
cache size, and more.

2. Setup Queries

As I mentioned before, there is no need to assign the name to a query  
anymore. You still need to select a cache policy. And there's one  
more optional setting that makes a query manageable via OSCache - an  
array of arbitrary cache groups. Those are used to expire groups of  
query results in one shot, and generally allow to assign queries to a  
given OS Cache policy definition. E.g.:

SelectQquery query = ...
query.setCachePolicy(QueryMetadata.LOCAL_CACHE);
query.setCacheGroups(new String[] {"g1", "g5"});

Andrus

Re: How the cache works ?

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Aug 1, 2007, at 5:06 PM, Jean-Paul Le Fèvre wrote:

>       query.setName("SimulationSelection");

In 3.0 Cayenne builds the cache key internally based on the query  
semantics [1]. It doesn't require a query name to be present and will  
ensure that queries with different qualifiers/orderings/fetch limits/ 
etc. do not override each other in the cache.

Before 3.0 Cayenne would use a name of the query as THE cache key. So  
if you have two queries with say different qualifiers, but same name,  
a cached result of the first query would be returned for the second  
one as well. I think you may be seeing this behavior. Until you can  
upgrade to 3.0, I suggest copying 3.0 cache key algorithm [1] to your  
own method that would generate a cache-friendly query name.

Andrus


[1] http://svn.apache.org/repos/asf/cayenne/main/trunk/framework/ 
cayenne-jdk1.4-unpublished/src/main/java/org/apache/cayenne/query/ 
SelectQueryMetadata.java