我有很多一对一的关系,比方说用户有一个公司。公司实体没有任何其他关系。

如果我为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上找到的关系和实体。查询不能被二级缓存缓存,并且将始终转到数据库(或查询缓存)。

09-10 01:39
查看更多