1

我们使用以下属性在休眠中启用了二级缓存:

hibernateProperties.setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory");
hibernateProperties.setProperty("hibernate.cache.use_query_cache", Boolean.TRUE.toString());
hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", Boolean.TRUE.toString());
hibernateProperties.setProperty("hibernate.cache.use_structured_entries", Boolean.TRUE.toString());     
hibernateProperties.setProperty("hibernate.cache.generate_statistics", Boolean.TRUE.toString());

并使用缓存标签标记我们的实体:

@Entity
@Indexed
@Table(name = "item")
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
public class Item implements Serializable {

这个实体有一个惰性集合,带有额外的惰性集合选项:

@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@ManyToMany(fetch = FetchType.LAZY, targetEntity = User.class, mappedBy = "likes")
@LazyCollection(LazyCollectionOption.EXTRA)
private List<User> users;

这似乎运作良好,在数据缓存后我看不到任何数据库查询,但我们看到的是调用日志

select count(user_id) from user_items where item_id =?

有没有办法让休眠来缓存惰性集合的大小,这样我们在执行 users.size() 时就不需要访问数据库?


我已更改为 CacheConcurrencyStrategy.READ_WRITE 并看到相同的行为。

在第一个请求中,我看到选择实体的查询和查找集合大小的查询。我看到日志消息说实体正在被缓存。

在随后的请求中,没有调用加载实体,但仍然调用查找集合的大小。

4

2 回答 2

-1

缓存数据时,您永远不会看到数据库查询。你是说有选择查询的连续日志。Ehcache 不提供事务缓存。你是说它正在工作。兄弟,它不起作用,您只是有相同的数据库调用和日志。 检查 Ehcache 文档,因为它不支持 TRANSACTIONAL 缓存

于 2013-03-01T10:40:36.357 回答
-1

用户列表是一个延迟加载的集合。在延迟加载的集合中,您将没有任何数据。每当您想要访问延迟加载的集合或想要确定延迟加载的集合的大小时,它必须具有有关其中数据的信息,例如那里有多少元素。为此,它将从数据库中获取该数据,因此每次都会生成数据库查询。我检查了最上层和其他一些对象内的列表。这表明当 List 不是顶级对象时,它将被延迟初始化。因此,每当您想获取有关集合的信息或从集合中获取信息时,它都会生成数据库查询。

于 2013-03-04T09:02:22.637 回答