hibernate - 缓存中未找到查询结果

标签 hibernate orm jpa caching ehcache

环境:JBoss 5.1、ehcache 2.1.0、hibernate 3.3.x、seam 2.2.0

ehcache.xml(2.1.0版本)包含以下几行,但我的查询结果在缓存中找不到。我是否应该为每个触发的查询设置一个缓存区域?我在这里缺少什么?

<!-- 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" />

最佳答案

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

不,你不是(除非你想要对它们进行细粒度的控制)。以下是文档关于该主题的内容:

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().

现在的问题是:

  • 您启用二级缓存了吗?
  • 您是否启用了查询所涉及实体的缓存?
  • 您是否真的通过调用 setCacheable(true) 来启用查询缓存?

这是不相关的,但我还建议激活 org.hibernate.cache 类别的日志记录。

另请参阅

关于hibernate - 缓存中未找到查询结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3315446/

相关文章:

cakephp - 使用独立的 CakePHP ORM 时在哪里定义表/实体类?

java - 如何在多个实体中使用通用实体

java - JPA 删除失败(违反完整性约束 : foreign key no action) - data model too convoluted?

java - 使用 @MapsId 保留 @OneToOne 子实体会在 Hibernate 中抛出 "error:detached entity passed to persist"

java - 如何使用 JPA 计算行数?

java - 没有外键的 JPA OneToOne 关联无法正常工作

java - Hibernate注解: Two relation types between two entities?

node.js - 给定 sql server 查询的等效 Sequelize 操作

java - 使用多对一映射编写插入 HQL 查询

java - 如果单行 SQL 中不满足条件,则回滚整个查询