我有很多一对一的关系,比方说用户有一个公司。公司实体没有任何其他关系。
如果我为Company的findAll休眠查询启用了二级缓存,则第二次我重新加载页面(这意味着加载了User,然后还加载了所有Company的列表),我将为每个现有公司选择(从Company中选择...在休眠输出中,其中id =?)。
在为公司调用findAll时会发生这种情况(这是类中的通用方法,并使用适当的类型进行了扩展):
return (List<T>) getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
Criteria c = session.createCriteria(persistentClass);
c.setCacheable(cacheFindAll);
return c.list();
}
});
我在只读策略中使用Jboss TreeCacheProvider。如果我使用
setCacheable(false)
,则没有“不需要的”选择。为什么会发生这种情况,如何消除这种现象?
最佳答案
调用 setCacheable() 用于启用查询缓存,请参阅javadoc:Enable caching of this query result, provided query caching is enabled for the underlying session
发生的是公司的ID被缓存,而不是对象本身。如果启用第二级缓存,这些单独的公司查询将由第二级缓存处理。
为了启用二级缓存,您需要在persistence.xml中设置hibernate.cache.use_second_level_cache = true。另外,您需要注释您要在二级缓存中缓存的关系和实体。
@OneToMany
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
private List<Company> companies;
和实体缓存:
@Entity
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Company {
...
}
顺便说一句,第二级缓存将仅缓存在id上找到的关系和实体。查询不能被二级缓存缓存,并且将始终转到数据库(或查询缓存)。