我在以下情况下收到以下异常:
java.lang.IllegalStateException: Session/EntityManager is closed
我正在创建一个事务,我在其中使用 session.save() 保存对象; 我还没有提交事务,但是我正在使用 flush 将数据发送到数据库。任何人都可以清除我的回滚概念吗?它是如何工作的?使用刷新而不提交。
任何人都可以在我的代码下面解释我,我刚刚开始学习 hibernate 。
Transaction tr1 = session.beginTransaction();
session.save(c1);
session.save(c2);
c3.setCustName("Robby");
session.save(c3);
session.flush();
tr1.rollback();
session.save(c4);//Here its throwing above mentioned exception.
session.save(c5);
tr1.commit();
提前致谢...!
最佳答案
在您的用例中,看起来您要完成的是在同一个 session 中执行两个事务。最简单的方法是这样的
Session session = // you acquire a session from somewhere
try {
// First trx
session.getTransaction().begin();
session.save( c1 );
session.save( c2 );
c3.setCustName( "Robby" );
session.save( c3 );
// at this point nothing has been sent to the database
// if you want to send it to the db and start a new trx
// you don't need to use flush, just commit it.
session.getTransaction().commit();
// Start a new trx
session.getTransaction().begin();
session.save( c4 );
session.save( c5 );
session.getTransaction().commit();
}
catch ( Exception e ) {
if ( session.getTransaction().isActive() ) {
session.getTransaction().rollback();
}
throw e;
}
finally {
if ( session != null && session.isOpen() ) {
session.close();
}
}
这样做的主要问题是,有可能第一个事务成功而没有问题,但第二个事务失败,这取决于您的用例,这可能意味着当您希望全部提交或什么都不提交时数据库状态不一致全部。
更好的实现是这样的:
Session session = // you acquire a session from somewhere
try {
// First trx
session.getTransaction().begin();
session.save( c1 );
session.save( c2 );
c3.setCustName( "Robby" );
session.save( c3 );
session.save( c4 );
session.save( c5 );
session.getTransaction().commit();
}
catch ( Exception e ) {
if ( session.getTransaction().isActive() ) {
session.getTransaction().rollback();
}
throw e;
}
finally {
if ( session != null && session.isOpen() ) {
session.close();
}
}
话虽如此,请理解当 Transaction
已被标记为回滚时,您可以调用 Transaction#rollback()
或执行相同操作的一些内部异常处理代码,那是无法撤消的。
此外,它通常意味着 session 缓存中的状态对于所有意图和目的都是未定义的。如果您查看大多数关于如何处理回滚的示例,您通常会看到唯一的选择是关闭该 session 并尝试从一个全新的 session 开始,而不仅仅是一个事务。
因此,您获得的异常是为了防止用户实质上使用 Session 或 EntityManager,其中持久上下文状态可能由于事件事务已被标记为回滚而未定义。
关于hibernate - 回滚是否终止 session ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50543040/