Hibernate 里 SQL 和 HQL,Criteria Query 对Session Cache缓存使用的不同

现在在做JBPM,JBPM里面有个接口是History Process Instance Query。 后来有需求查找的时候要和实际业务中的数据关联,考虑到性能,希望把业务表和JBPM的表关联起来,所以我扩展了一下这个接口,用的也是JBPM的Command模板,调用CommandService执行,不同就只是我写的是SQL,JBPM用的是HQL。

今天出现了个异常,我们创建了一个Process,在没结束前,立即用我写的那个接口去查,发现查不到刚创建的那条数据,很奇怪。理论上来说,虽然数据没有被commit到db,但是应该在session中的,查询也要能查到。

Debug一下,又发现同样的查找,用SQL查不到,用HQL却能查得到,崩溃。。最奇怪的是,在用HQL查完后,再用同样的SQL再查一次,又能查到数据了。 顿时我觉得是bug。哈哈

我猜想可能是SQL查询不会去看session,所以拿不到,那为什么HQL查完后,SQL查又能有呢? 可能是Hibernate缓存了查找,因为他们的搜索条件是一样的,所以匹配了HQL查找的结果。是不是这样呢?

跟踪代码(基于hibernate 3.3.1.GA)。在进入SessionImpl后,SQL查找和HQL查找会进入不同的方法,分别是:

SQL  public List listCustomQuery(CustomQuery customQuery, QueryParameters queryParameters)   line 1706

HQL public List list(String query, QueryParameters queryParameters) line 1136

其实还有一个同样性质的方法在 line1567 public List list(CriteriaImpl criteria),这个应该是给Criteria Query用的。

这三个方法都有调用同一个方法: line:987  autoFlushIfRequired(spaces)

看这个方法的解释

/**
     * detect in-memory changes, determine if the changes are to tables
     * named in the query and, if so, complete execution the flush
     */

知道了,hibernate会看查找的对象(spaces参数)在hibernate session中有没有缓存在session中数据,如果有就会提交到DB。

这里的提交不是transaction的commit ! 指把hibernate session的数据同步到db 的同一个session中,两个session在不同地方,但是还是没有commit,调session.flush就能达到效果。

关键是,发现在HQL查找的时候,传给autoFlushIfRequired的参数是要查找的对象名字,但是在SQL查找的时候却是空的。

原因找到了,因为在SQL查找的时候没有flush,在HQL查找的时候flush了,所以结果不一致了。也能解释为什么HQL查找完,SQL查就是对的了。

为什么SQL查没有传对参数呢? 跟了好久,一层套一层,放弃,懒得找。呵呵

感觉应该是bug吧,不是的话,就不要在listCustomQuery里调用autoFlushIfRequired了。 也有可能是些SQL的时候有些技巧,以后再研究研究。先调session.flush()把问题绕过再说,哈哈。

Update:又看了下代码,调用autoFlushIfRequired有去判断一个条件,那个条件大概指这个查询影响到的对象。这个条件是在查询创建的时候就应该确定的,但是SQL查询没有设这个值,所以忽略了。要扩展,更改SQL查询创建的那块代码就行了。

后来搜了一篇文章:

http://i-proving.ca/space/Technologies/Hibernate/SQL+vs+HQL+with+the+Session+Cache

里面的图还是不错的,看一下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值