使用Hibernate 3.3.0和ehcache 1.2.3打开二级缓存和查询缓存,我意识到以下代码在多个调用中返回相同的序列号,导致插入失败。
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session) throws HibernateException, SQLException {
StringBuilder strQuery = new StringBuilder();
strQuery.append("SELECT ");
strQuery.append(sequenceName);
strQuery.append(".nextval as nextSequence FROM dual d");
Query query = session.createSQLQuery(strQuery.toString()).addScalar("nextSequence", Hibernate.STRING);
return query.uniqueResult();
}
};
return this.hibernateTemplate.execute(callback).toString();如果在执行查询之前关闭查询缓存或添加以下行,代码将正常工作。
query.setCacheable(false);这是令人困惑的,因为Hibernate文档清楚地声明
大多数查询都不能从缓存中获益,因此默认情况下,查询不会被缓存。要启用缓存,请调用Query.setCacheable(true)。此调用允许查询查找现有的缓存结果,或在执行结果时将其结果添加到缓存中。
在这种情况下,这种行为是否异常,我仍然可以假设默认情况下没有缓存查询吗?
发布于 2012-02-14 10:10:52
查询缓存是一种非常简单的机制,它存储特定密钥的结果。在本机查询的情况下,该键将是查询本身和所有params的关键字。
因此,例如,关键可能是:
*----------------------------------------------------------------------------------------*
| Query Cache |
|----------------------------------------------------------------------------------------|
| ["select * from table as t where t.id=? and p.column=?", [ 1 , "value"] ] -> [ 2 ] ] |
*----------------------------------------------------------------------------------------*从这个角度来看,每个查询都可以缓存--在某些情况下。当然,查询必须由Hibernate类处理,而不是直接通过JDBC连接处理。
而且,BTW,很容易找到您的查询是否将使用查询缓存!所有这些都在org.hibernate.cache下的日志文件中。
所有这些都有一个很大的问题--如果您运行本地查询,它将清除第二级缓存的所有实体和记录!至少在我使用的最后一个版本之前是这样的!因此,您可以使用本机查询,但由于Hibernate不能决定它们做什么,所以将清除缓存,以避免该查询所做的数据更改,而缓存对象中没有反映。
因此,查询缓存存在很多问题,您应该考虑是否真的想使用该特性!看一下这篇文章或这一个。我试图避免在我的工作中使用查询缓存,我只对实体使用SLC .
https://stackoverflow.com/questions/5740618
复制相似问题