如何打破Hibernate会话?

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非常聪明,可以在不破坏整个会话的情况下重新打开引擎盖下的断开连接.

所以这可能不是一个关键问题,因为我们的应用程序似乎足够强大,即使是原始形式.但是,这个问题一直困扰着我.我想知道:

  1. 在什么情况下,Hibernate会话在HibernateException被抛出后真的变得无法使用(更新:以及有什么症状)?
  2. 如何在测试中重现这一点(更新:最好是集成,而不是单元测试)?
  3. (这种测试的正确用语是什么?)

Pas*_*ent 4

什么情况下 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?
Run Code Online (Sandbox Code Playgroud)

但我不确定这能证明什么。我的意思是,如果会议仍在进行,我们只能针对这个特殊情况得出结论。

更新:忘记我的建议,它不能证明任何事情。实际上,我认为在HibernateException. 因此,我认为正确的做法是遵循建议(或建议的替代方案,但我只会为每个事务请求一个新的值Sessionclose无论是否抛出异常),而不是试图证明任何事情。

这种测试的正确术语是什么?

集成测试?稳健性测试?