【问题标题】:Hibernate does not rollback in case of a runtime exception thrown如果抛出运行时异常,Hibernate 不会回滚
【发布时间】:2018-11-26 04:00:46
【问题描述】:
我的项目中有以下代码。第 4 行抛出异常,但我的产品详细信息仍被保存。我很难理解为什么即使在抛出异常后它也会保存产品详细信息
我还想了解第 4 行抛出的异常是检查异常还是未检查异常?如果我抛出“抛出新异常(“详细信息不匹配”)”,这是我假设的运行时异常?
class Product{
@Transactional
addDetails(){
try{
}
catch (Exception e) {
throw new Exception("Details dont match") //Line 4
}
productDAO.save(productDetails)
addAdditionalDetails(productDetails)
}
}
class ProductDAO {
@Transactional
public void save(Product productDetails){
entitiyManager.merge(productDetails)
}
}
【问题讨论】:
标签:
java
hibernate
spring-jdbc
spring-orm
【解决方案1】:
我也想了解第 4 行抛出的异常是否是
已检查或未检查的异常?
答案:java.lang.Exception 是一个检查异常。
如果我抛出 "throw new Exception("Details don't match")" 这是一个
我假设的运行时异常?
回答:不,它不是RuntimeException。 RuntimeException 是扩展 java.lang.RuntimeException 或其 subclass 的那些。
在春季发生Runtime 异常时,事务是回滚。这意味着在extends RuntimeException 或其子类的事务中抛出的任何异常都会回滚它。但是在您的情况下,您正在抛出Exception,这不是RuntimeException 的类型。
解决方案:
我会建议创建一个扩展 RuntimeExction 的自定义异常并抛出它。
class UnmatchedDetailException extends RuntimeException{
UnmatchedDetailException(String msg){
super(msg);
}
}
然后抛出UnmatchedDetailException
throw new UnmatchedDetailException("Deatils not matched");
【解决方案2】:
使用默认的 spring 配置,只有未检查的运行时异常会被回滚。为了自定义此配置,rollbackFor 用作 @Transactional 注释中的属性。
例如,
@Transactional(rollbackFor = { MyInvalidUserException.class,
MyApplicationException.class }) public void method() throws
我的无效用户异常,我的应用程序异常 {
...
... }