当程序遇到异常时,RollBackOnly变为True。
如何将此RollBack“设置”为False即使遇到异常。
@Resource
protected SessionContext context;
Public void creerNewEntity(final Entity myEntity) {
try {
this.em.persist(myEntity);
this.em.flush();
} catch (final EntityExistsException e) {
System.out.println((this.context.getRollbackOnly())); // It s has a true value
throw new MyException("TODO BLABLA", e);
}
}
当程序抛出此异常“MyException
”时,我会通过设置新ID来更改对象myEntity
,然后再次调用creerNewEntity()
。
不幸的是,它不起作用,我得到了这个异常“javax.persistence.PersistenceException: org.hibernate.HibernateException: proxy handle is no longer valid
”,我认为因为RollBack有一个真正的值,我怎样才能改变回滚以使其有效?
感谢。
答案 0 :(得分:2)
可能没有一种简单的方法可以做到这一点,因为EJB设计的重点在于你不关心这些事情。事务内部的第一个错误使其无效 - >回滚。这是规则。
如果您想要一些特殊的东西,那么从会话中获取数据库连接并使用纯SQL而不是EJB来修改数据。这样,您可以尝试INSERT
一个新实例并自己处理所有异常。插入成功后,您可以使用EJB加载新创建的对象以将其添加到会话中。
那就是说,我不确定你要用上面的代码实现什么。只是忽略当你无法在数据库中创建新实例时,感觉就像“我不关心我的产品的质量”。也许您尝试解决错误只是应用程序设计错误的一个症状。退后一步,考虑一下你在做什么以及为什么。也许如果你告诉我们更多关于你想忽略所有错误的原因(即使是非常致命的错误),我们也能指出更好的解决方案。
编辑所以你得到javax.persistence.EntityExistsException
,这意味着你试图两次保存同一个实体。这可能意味着许多事情:
正确的解决方案取决于您需要实现的目标。如果您修改了myEntity
并需要保存更改,请使用em.merge()
。然后EM将检查对象是否已经存在,如果存在,它将执行SQL UPDATE
而不是INSERT
如果您只想给其他类一个有效的实体,那么您需要从数据库中获取它。如果数据库返回null,则需要创建一个新实例并将其保留,然后将其返回。
答案 1 :(得分:0)
EntityExistsException
是PersistenceException
当jpa抛出它时,ejb CMT被标记为回滚
http://piotrnowicki.com/2013/03/jpa-and-cmt-why-catching-persistence-exception-is-not-enough/
如aaron建议的那样,你可以使用merge()
您还可以使用RequiresNew
包含事务边界@TransactionAttribute(REQUIRES_NEW)