2015-05-11 327 views
2

在我们的应用程序中,我们正在服务层应用使用注释的春季声明式交易。服务层的春季交易

在这里,我不知道如何正确处理异常。

我的要求是什么,当dao层抛出任何hibernate异常时,我们将回滚事务,但是在一种情况下,我得到InvalidDataAccessResourceUsageException,因为存在唯一的索引违例发生。所以我想在这里做的是我想在服务类中捕获InvalidDataAccessResourceUsageException异常,并且必须重新抛出应用程序特定异常给控制器。

但是,这里发生的事情是因为我们有服务层类的事务分界,在执行该方法后会话在服务层(即,当tx提交时)正在刷新,因此我无法将其捕获到相同的方法中,直接传播给控制器。

请建议我解决这个问题。

也在寻求一个更澄清,假设我有一个像下面

@Transactional(value="transactionManager",readOnly = false, propagation = Propagation.REQUIRED,rollbackFor = HibernateException.class) 
public SomeDTO editObject(SomeDTO someDto, String user) throws  EditException {   
    try{ 
     /* 
     call to dao.edit(); 
     another call to anotherDao.addEditsTOAnotherTable(); 
     some business logic*/  
    } catch(HibernateException e){ 
    } catch(InvalidDataAccessResourceUsageException ie){}  
} 

我能赶上的异常如上面的方法。注意:我没有处理或抛出dao的任何异常。在dao层也没有像FlushMode.ALWAYS等会话缓存机制,因为它将在tx.commit()期间刷新。

+0

检查,你不会在插入之前打破唯一索引之前检查所有数据库的约束。或者直接调用flush()。 –

+0

我只是想告诉用户有关唯一索引违规的情况。请让我知道,如果我们有任何其他的处理它,而不是冲洗替代品。 – Jai

+0

正如我所说:你可以检查你不会破坏独特的索引插入之前 –

回答

0

默认@Transactional将回滚任何RuntimeException,由于HibernateExceptionRuntimeException,回滚将automaticaly做,你不必添加rollbackFor = HibernateException.class 您可以处理例外是这样的:

try{ 
}catch(InvalidDataAccessResourceUsageException e){ 
throw new YourApplicationExceptionNotUniqueIndex(); 
} 

和:

YourApplicationExceptionNotUniqueIndex shoud extendsRuntimeException这样你将在你的服务层有一个回滚,你可以在你的控制器捕获异常。

+0

但是在这里我需要捕获HibernateException并想重新抛出ApplicationSpecificException。这就是为什么我有服务方法中的HIbernateException catch块。但是我无法捕捉到Hibernate异常事件,尽管发生了任何HibernateException。我只能在dao中显式刷新会话时才能捕获它。我想知道为什么当tx.commit()发生时我无法捕捉它。 – Jai

+0

InvalidDataAccessResourceUsageException也是运行时异常。 – Jai

-1

更好地处理编辑成数据库