DB表test有条数据:
id           username 
-----------------
1            name1
我在hibernate中:
begin transaction://第一次查询
Test test = (Test)session.createQuery("from Test t where t.id = 1").list().get(0);
test.setUsername("name2");
//第二次查询
Test testOther = (Test)session.createQuery("from Test t where t.id = 1").list().get(0);
System.out.println("查询出来的名字为:"+testOther.getUsername());end transaction:结果为<打开了showsql>:
Hibernate: select test0_.id as id4_, test0_.username as username4_, from test test0_ where test0_.id=?
Hibernate: update test set username=? where id=?
Hibernate: select test0_.id as id4_, test0_.username as username4_, from test test0_ where test0_.id=?
查询出来的名字为:name2疑问:
为什么第二次查询出来的是name2,而不是name1,我看《深入浅出hibernate》以及网上很多资料都说,如果以createQuery().list()查询出来的是只写缓存而不读缓存的,也就是说怎么都会去查询数据库,而不是查询缓存,这个就奇怪了,我第二次
查询时,明明第一个更新还没提交,那么数据库中的值还是为name1,为什么第二次查询发出了sql语句去查DB,得出来的值却
不是name1;难道书上说的都是错的,这里是从缓存中查出来的?

解决方案 »

  1.   

    是hibernate3版本,并且没打开二级缓存和查询缓存,难道list先发出sql,再从一级缓存中拿对象?那这样
    岂不是得不尝失,还不如直接从一级缓存中拿算了。
      

  2.   

    test的状态是 持久态(Persistent)持久状态的对象发生改变 hibernate 会监测到 所以会发送update语句
      

  3.   


    不是list先发出sql,再从一级缓存中拿对象
    应该是list根本就不查一级缓存
      

  4.   

    书上也是这么说的,不从一级缓存拿,看结果也的确是发出了sql查询数据库,那么既然list不从一级缓存拿,是查询数据库,那么为什么得出来是我未提交的数据,而不是数据库中真实的数据,我第二次查询可是在更新未提交的时候查询的,查询完毕后才提交.
      

  5.   

    在这先谢谢noaso回贴,刚跟了一下源码,找到原因了,结贴。
      

  6.   

    原因是test.setUsername("name2");
    同步了数据库 所以你第二次查出来是name2了
      

  7.   

    对啊,已经是更新了数据库的值了,你看你打印的都是啊,第二个就已经update数据库了,当然变了
      

  8.   

    Hibernate: select test0_.id as id4_, test0_.username as username4_, from test test0_ where test0_.id=?
    Hibernate: update test set username=? where id=?
    Hibernate: select test0_.id as id4_, test0_.username as username4_, from test test0_ where test0_.id=
    看Hibernate: update test set username=? where id=?已经update到数据里了,此时的test被Hibernate管理,无论做什么修改都会同步到数据库,跟EJB的托管什么之类一样
      

  9.   

    第一点.如2楼所说.test的状态是 持久态(Persistent)
    持久状态的对象发生改变 hibernate 会监测到 所以会发送update语句,
    一旦你set某个属性之后,test的状态就变成瞬时的,但是你又没有进行update的操作,所以对象依然是瞬时,在查询
    Test testOther = (Test)session.createQuery("from Test t where t.id = 1").list().get(0);
    的时候, 是从缓存中拿的.
    我估计你数据库中的数据还是name1..书上没说错.你也没理解错.Hibernate对象的三种状态你可以了解了解.
    如果有说错.麻烦大牛s指正.
      

  10.   

    最核心的一点就是list()方法不查询一级缓存(session缓存),还有就是#2说的test的状态是 持久态(Persistent)持久状态的对象发生改变 hibernate 会监测到 所以会发送update语句
      

  11.   

    最直接的就是hibernate会根据主键到缓存里找数据、