hibernate - 打开Hibernate查询缓存后,默认情况下是否缓存 native SQL查询?

标签 hibernate caching ehcache

使用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文档明确指出

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.



在这种情况下,这是否是异常行为,我是否仍然可以假设默认情况下不缓存查询?

最佳答案

查询缓存是一种非常简单的机制,用于存储某些键的结果。在 native 查询的情况下,该键将是您自己的查询以及所有参数。

因此,例如, key 可能是:

*----------------------------------------------------------------------------------------*
|                                    Query Cache                                         |
|----------------------------------------------------------------------------------------|
| ["select * from table as t where t.id=? and p.column=?", [ 1 , "value"] ] -> [  2 ] ]  |
*----------------------------------------------------------------------------------------*

从这个角度来看,在某些情况下,每个查询都可以缓存。当然,查询必须由Hibernate类处理,而不是直接通过JDBC连接处理。

而且,顺便说一句,很容易找出您的查询是否将使用查询缓存!全部都在org.hibernate.cache下的日志文件中。

所有这些都有很大的收获-如果您运行 native 查询,它将驱逐第二级缓存的所有实体和记录!至少直到我使用的上一个版本为止!因此,您可以使用 native 查询,但是由于Hibernate无法决定它们的作用,因此它将清除缓存,以避免此查询所做的数据更改未反射(reflect)在缓存对象中。

因此,查询缓存存在很多问题,您应该考虑是否真的要使用该功能! Take a look at this articlethis one。我试图避免在我的工作中使用查询缓存,我只对实体使用SLC ...

关于hibernate - 打开Hibernate查询缓存后,默认情况下是否缓存 native SQL查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5740618/

相关文章:

java - 无法访问 TransactionManager 或 UserTransaction 来进行物理事务委托(delegate)

java - 无法在 hibernate 和 spring mvc 中添加或更新外键

java - 从 Jboss EAP 6.0 提供静态文件

c# - C# 的对象缓存

java - 使用空字符串而不是 null - 一个好的做法?

caching - 如何 "add"代理部分将注册表配置为直通缓存?

java - 如何使用ehcache或JCS作为队列或流式缓存?

java - ehcache 是否与 servlet 容器运行在同一个进程中?

java - 在 Terracotta 集群上创建两个不同的缓存时出现 NullPointerException

java - ehcache 磁盘存储中的元素不会过期