Pét*_*rök 13 java testing session hibernate exception
在Hibernate参考中,有几次说明
Hibernate抛出的所有异常都是致命的.这意味着您必须回滚数据库事务并关闭当前事务
Session.您不能继续使用Session引发异常的操作.
我们的一个遗留应用程序使用单个会话将文件中的许多记录更新/插入到数据库表中.每个记录更新/插入都在单独的事务中完成,然后提交(或在发生错误时回滚).然后为下一条记录打开一个新事务,依此类推.但是在整个过程中使用相同的会话,即使在处理过程HibernateException中陷入了困境.我们在JBoss 4.2上使用Oracle 9i btw和Hibernate 3.24.sp1.
阅读本书中的上述内容,我意识到这种设计可能会失败.所以我重构了应用程序,为每次记录更新使用单独的会话.在使用模拟会话工厂的单元测试中,我可以验证它现在正在为每个记录更新请求新会话.到现在为止还挺好.
但是,我们发现在测试整个应用程序时没有办法重现会话失败(这是一个压力测试btw,还是......?).我们考虑过关闭数据库的监听器,但我们意识到应用程序正在保持一堆连接对数据库开放,并且监听器不会影响这些连接.(这是一个Web应用程序,每晚由调度程序激活一次,但它也可以通过浏览器激活.)然后我们尝试在应用程序处理更新时杀死数据库中的一些连接 - 这导致一些失败更新,但随后应用程序愉快地继续更新其余记录.显然,Hibernate非常聪明,可以在不破坏整个会话的情况下重新打开引擎盖下的断开连接.
所以这可能不是一个关键问题,因为我们的应用程序似乎足够强大,即使是原始形式.但是,这个问题一直困扰着我.我想知道:
HibernateException被抛出后真的变得无法使用(更新:以及有什么症状)?什么情况下 Hibernate 会话在抛出 HibernateException 后确实变得不可用?
有趣的问题。我很确定我见过这样的情况,在这种异常之后会话仍然“工作”。问题是这可能无法得到保证。我需要进一步挖掘这一点。
更新:引用Hibernate 论坛中一位 Hibernate 开发人员的消息:
当任何异常发生时,休眠会话应该被丢弃。它可能会处于相对于数据库不一致的状态。只读会话的情况并非如此,因为它不使用任何会话级缓存。或者,您可以在发生异常时清除会话级缓存(但我个人不喜欢这种方法,因为它不是一个干净的解决方案,并且可能会导致未来的问题)。
因此,问题并不在于它是否Session“技术上可用”,问题在于它可能不会按预期运行。而你显然不希望这样。
如何在测试中重现这一点?
您可以故意违反导致子类被抛出的条件,例如通过违反完整性约束来获取ConstraintViolationException. 类似这样的事情怎么样:
Session session = HibernateUtil.getCurrentSession();
try {
    session.beginTransaction();    
    // execute some code that violates a unique constraint
    ...
    session.getTransaction().commit();  
} catch (HibernateException e) {
    session.getTransaction().rollback();
}
// keep using the session
try {
    session.beginTransaction();    
    ...
    session.getTransaction().commit();  
} catch (HibernateException e) {
    session.getTransaction().rollback();
}
// do we reach this point?
但我不确定这能证明什么。我的意思是,如果会议仍在进行,我们只能针对这个特殊情况得出结论。
更新:忘记我的建议,它不能证明任何事情。实际上,我认为在HibernateException. 因此,我认为正确的做法是遵循建议(或建议的替代方案,但我只会为每个事务请求一个新的值Session,close无论是否抛出异常),而不是试图证明任何事情。
这种测试的正确术语是什么?
集成测试?稳健性测试?
| 归档时间: | 
 | 
| 查看次数: | 6509 次 | 
| 最近记录: |