得想想Hibernate 的生存周期和运行过程了

解决方案 »

  1.   

    最基本的问题我想问一下,用JUnit调用getUserByNameAndPassword(XX,XX)可以通过,而正常情况下为什么不能通过? 没有道理的关掉服务器,重启,就OK了,
    这可能是因为在hibernate里面默认情况下hibernate.connection.autocommit是false的,也就是说insert执行了,但没有提交,关闭服务器的时候才提交的
      

  2.   

    这可能是因为在hibernate里面默认情况下hibernate.connection.autocommit是false的,也就是说insert执行了,但没有提交,关闭服务器的时候才提交的
    ============================================================
    这个也不大可能,因为"查看数据库,数据插入到了数据库中.",如果没有提交的话,数据库应该是没有值的.
      

  3.   

    这可能是因为在hibernate里面默认情况下hibernate.connection.autocommit是false的,也就是说insert执行了,但没有提交,关闭服务器的时候才提交的
    ============================================================
    这个也不大可能,因为"查看数据库,数据插入到了数据库中.",如果没有提交的话,数据库应该是没有值的.
    ======================================
    到底有没有值呢?
      

  4.   

    我也觉得应该是laoxing521(想做程序员的农民)说的情况
      

  5.   

    在注册后,数据库肯定是有值的,所以应该是commit的,但是调用查询的语句确实查不出来,它是通过createQuery("from User u where u.userName=? and password=? ")这样找的,我后来把这段改成createCrital(User.class).add(Expression.eq"")这种形式也是一样的结果..估计问题不是出在这个地方
    我这题是现场调试的,唉...丢脸啊
      

  6.   

    我觉着如果真是提示找不到getUserByNameAndPassword方法,而junit测试可以的话,可能是服务器加载的类和当前的类版本不一直,一般用最新版的类把老版的类重新覆盖,并使应用重新reload一下应该就可以。
      

  7.   

    我首先也怀疑web server没有load最新的类,就是sansong089说的。但是如果这个错误可以重复出现的话,就不是这个问题了。但是你说你把HQL改了,仍出现这个问题,说明不是因为web server没有加载最新类的关系。你有没有看他的session是怎么管理的?
      

  8.   

    我怎么觉得是session过期了等等类似的东西?既然数据库有值了又测试通过了,那和Hibernate没关系了吧?
      

  9.   

    那就是web容器有错误,导致你验证不成功,实际hibernate没问题,
    重启后web容器没问题啦,就OK了。
      

  10.   

    可能因为配置了readOnly二级缓存
      

  11.   

    JUnit调用难道和实际调用有什么不同吗?!
      

  12.   

    有一个疑问阿,如果不执行这个操作---“此时服务器不关,直接执行JUnit的测试文件,调用该方法,能找到这个用户的注册信息, ”---重起之后,可以正常登陆么???
      

  13.   

    getUserByNameAndPassword(用户名,密码)这个方法的实现需要看一下,需要确定它到底有没有去数据库里读
      

  14.   

    在调用这个getUserByNameAndPassword之前将session清空一下应该就OK了
      

  15.   

    应该是hibernate缓存的问题.在注册完以后只是把数据保存在了缓存里面,而没有提交到数据库.
    当你用Junit测试的时候当然可以测成功,因为hibernate是先查看缓存的.如果缓存里面有它想要的东西就不查数据库了,直接拿过来用.如果没有才查的.
    至于LZ说的关闭服务器以后,重起就可以登陆了.那应该是在关闭服务器的同时,hibernate commit了缓存里面的数据.
      

  16.   

    提交以后,应该还在缓存中,没有到数据库里,可以加一条语句,session.falsh();
    或者一下
      

  17.   

    个人觉得不可能出现这样的情况
    如果真的有问题的话 
    只有一种可能 在数据插入之后 数据库出现问题 重启
    导致 connection reset
    web server 无法连接到数据库
    而junit重新构建sessionfactory 可以连接到重启后的数据库
      

  18.   

    “此时服务器不关,直接执行JUnit的测试文件,调用该方法,能找到这个用户的注册信息”,显然说明注册的insert语句是经过提交的所以楼上关于“这可能是因为在hibernate里面默认情况下hibernate.connection.autocommit是false的,也就是说insert执行了,但没有提交,关闭服务器的时候才提交的”的说法错误getUserByNameAndPassword(用户名,密码)方法得不到用户很可能是hibernate的缓存机制没有控制好,导致该方法读取用户验证时并不是从数据库读取,而是从hibernate的session中读取,session由于还是原先没插值前的缓存,所以得不到用户
    个人认为2中解决方法:
    1.在getUserByNameAndPassword(用户名,密码)方法中加上HibernateSessionFactory.getSession().clear();
    2.在session.save()方法里面(也就是insert)在插入了注册的用户信息,事务提交后,调用session.close()方法将session关闭
      

  19.   

    多半你的事务配置有问题,要不你手动commit
      

  20.   

    上面很多兄弟在说是因为事务没有提交的原因,如果在执行save操作的时候没有提交,重新启动服务器时又怎么会提交呢?所有应该不是事务的问题。在hibernate进行save操作的时候,它会将save的这条数据同时缓存进session和sessionFactory(如果有配二级缓存的话)。当下次来查询的时候,Hibernate会先从查询sessionFactory,如果没有查到,继续查询session,如果还是没有查询到,就查询数据库。但现在的现象好像是,hibernate查询了session没有查到之后,就没有继续进行查询了,而是就返回结果了。这一点没有相通为什么。find操作和save操作应该是不会共享session的,因为session是非线程安全的。
    会不会是在二级缓存的时候出了问题,我记得在二级缓存中好像有一个类似“黑名单”的东西,里面保存了没有记录的查询语句,当hibernate发行这条查询语句在这个“黑名单”中的时候,它就不会继续查询数据库了,而是直接返回没有找到数据。但是在执行了save操作之后这条查询语句怎么会进入黑名单的呢?好像又不符合逻辑!以上是小弟的分析,希望抛砖引玉,大家继续讨论!
      

  21.   

    是缓存的问题,类似的情况我曾经碰到过。原因和这位老兄说的差不多:
    -----------
     xiaolei2656277() ( ) 信誉:100    Blog  2007-3-20 11:05:52  得分: 0     
    应该是hibernate缓存的问题.在注册完以后只是把数据保存在了缓存里面,而没有提交到数据库.
    当你用Junit测试的时候当然可以测成功,因为hibernate是先查看缓存的.如果缓存里面有它想要的东西就不查数据库了,直接拿过来用.如果没有才查的.
    至于LZ说的关闭服务器以后,重起就可以登陆了.那应该是在关闭服务器的同时,hibernate commit了缓存里面的数据.
      

  22.   

    感觉是缓存的问题一般操作后是不会立即提交数据库的,而是暂存在缓存中,除非你把FlushMode设成立即刷新模式你说的查询数据库有数据,你用的是什么方式?是直接在数据里看的还是通过hibernate查询的
      

  23.   

    YES,楼主应该说明,注册完以后,查看数据库,数据插入到了数据库中   
    这句话是说直接到数据库里查看的,还是用hibernate查询出来的
    如果是后者,那么很可能是session的问题,flush一下就行了
    前者的话,汗,请高手来答吧...
      

  24.   

    其实这个应该是缓存问题的一种错误使用方式造成的。他应该是在getUserByNameAndPassword里用的get()或者load()这种方法去获取的数据。这2种方法都是从缓存里去读取数据。只有find()是直接从数据库拿数据。而他的数据库的连接方式可能是注册时开启了一个连接,之后并未马上关闭,之后登陆时用的同一个连接,所以是不会从数据库拿数据的。重起服务器之后,是因为连接里的数据更新了,所以是可以得到数据的。
    解决方式可以有好几种了。将获得数据该成每次都从数据库拿的方式,或者是上面说的将session里的流清空掉,还可以再开起一个连接。你可以根据需要来决定。
    至于配置,可以不需要做高级的属性设置的。
      

  25.   

    补充一下,Junit测试是因为它每次连接都是新的,这个应该不用再做什么说明了吧。
      

  26.   

    hibernate我刚用过,一直出现这种缓存的问题,疑惑的是刷新页面就可以得到结果,后来IE的cache也清空了,仍然是不行。后来也想过,可以就是hibernate自身的session缓存问题,不是说有个属性设置为false就可以的么。可是呢,仍然不行,所以现在我已经不用hibernate了,还是直接用的struts的runner来做的,我们需要的就是重新取最新的数据,何必让hibernate自己找缓存,再找数据库呢??也许有人说效率问题,靠,如果是取出一次来就不用再取的数据,变成全局的让大家用难道不行???效率能差哪啊???要是做移动的,那没准,可是也用不到hibernate啊,还是劝大家以后不用hibernate为秒了。