views:

38

answers:

1

Env: JBoss 5.1, ehcache 2.1.0, hibernate 3.3.x, seam 2.2.0

ehcache.xml (2.1.0 version) contains the following lines, but my query results are not found in cache. Am I supposed to set a cache region for each of the queries which are fired. What am I missing here?

<!-- Cache configuration -->
<cache name="org.hibernate.cache.UpdateTimestampsCache"
    maxElementsInMemory="5000" eternal="true" timeToIdleSeconds="300"
    timeToLiveSeconds="300" overflowToDisk="true" diskPersistent="false"
    diskExpiryThreadIntervalSeconds="300" memoryStoreEvictionPolicy="LRU" />

<cache name="org.hibernate.cache.StandardQueryCache"
    maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="300"
    timeToLiveSeconds="300" overflowToDisk="true" diskPersistent="false"
    diskExpiryThreadIntervalSeconds="300" memoryStoreEvictionPolicy="LRU" />
A: 

Am I supposed to set a cache region for each of the queries which are fired. What am I missing here?

No you're not (unless you want a fine-grained control on them). Here is what the Documentation has to say on the topic:

19.4. The Query Cache

Query result sets can also be cached. This is only useful for queries that are run frequently with the same parameters. You will first need to enable the query cache:

hibernate.cache.use_query_cache true

This setting creates two new cache regions: one holding cached query result sets (org.hibernate.cache.StandardQueryCache), the other holding timestamps of the most recent updates to queryable tables (org.hibernate.cache.UpdateTimestampsCache). Note that the query cache does not cache the state of the actual entities in the result set; it caches only identifier values and results of value type. The query cache should always be used in conjunction with the second-level cache.

Most queries do not benefit from caching, so by default, queries are not cached. To enable caching, call Query.setCacheable(true). This call allows the query to look for existing cache results or add its results to the cache when it is executed.

If you require fine-grained control over query cache expiration policies, you can specify a named cache region for a particular query by calling Query.setCacheRegion().

List blogs = sess.createQuery("from Blog blog where blog.blogger = :blogger")
    .setEntity("blogger", blogger)
    .setMaxResults(15)
    .setCacheable(true)
    .setCacheRegion("frontpages")
    .list();

If the query should force a refresh of its query cache region, you should call Query.setCacheMode(CacheMode.REFRESH). This is particularly useful in cases where underlying data may have been updated via a separate process (i.e., not modified through Hibernate) and allows the application to selectively refresh particular query result sets. This is a more efficient alternative to eviction of a query cache region via SessionFactory.evictQueries().

Now, the question are:

  • did you enable the second level cache?
  • did you enable the caching of the entities your query is about?
  • do you actually enable caching of your query by calling setCacheable(true)?

This is unrelated but I also suggest to activate logging of the org.hibernate.cache category.

See also

Pascal Thivent
I have enabled second level cache.<property name="hibernate.cache.use_second_level_cache" value="${db.jpa.hibernate.cache.use_second_level_cache}"/><property name="hibernate.cache.use_query_cache"value="${db.jpa.hibernate.cache.use_query_cache}"/>@Cache annotations has been added to the entity classes@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)We use the EntityQuery framework and hence we set the setHints() method with cacheable flag set to trueI have enabled logging, hence I found out that the query results were not cached
Samuel
@Samuel: That's the kind of "details" that would be worth mentioning in your question. It might help to get better answers (and readers would not waste their time).
Pascal Thivent
I agree, should have done that as part of the question itself
Samuel