2012-12-07 53 views
2

我正在用Spring MVC和hibernate开发一个用于持久化的web应用程序。 鉴于吾道其中GenericDao有一个SessionFactory的成员属性:用Spring的@Transactional处理异常

@Repository 
public class Dao extends GenericDao { 
    public void save(Object o) { 
     getCurrentSession().save(o); 
    } 
} 

与服务类

@Service 
public class MyService { 
    @Autowired 
    Dao dao; 

    @Transactional 
    public void save(Object o) { 
     dao.save(o); 
    } 
} 

我想如果持续发生异常(约束,复制等)来通知我的用户。据我所知,@Transactional注释只适用于异常冒泡,事务管理器回滚,所以我不应该在该方法中处理异常。我应该在哪里以及如何捕获在DAO中发生的异常,以便我可以直接将其呈现给我的用户,或者将其包装在我自己的异常中?

我想使用spring的事务支持。

+0

在最基本的术语中,它是用户界面。在MVC中,它包含视图和控制器。 –

回答

4

Spring提供异常处理程序。

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-exceptionhandlers

所以,你可以有这样的事情在你的控制器来处理ConstraintViolationException

@ExceptionHandler(ConstraintViolationException.class) 
    public ModelAndView handleConstraintViolationException(IOException ex, Command command, HttpServletRequest request) 
{ 
    return new ModelAndView("ConstraintViolationExceptionView"); 
} 
+0

与此相关的问题是,没有任何异常(选中或取消选中)会转义用'@ Transactional'注释的服务方法。它在内部被捕获并且事务被回滚。所以你无法访问它。我很好奇,好像有一种方法可以得到它,同时仍然使用'@ Transactional' –

0

解决这个问题追了一段时间后,我解决了这个使用异常处理程序(如描述在另一个答案中)以及@Transactional注释的rollbackFor属性:

@Transactional(rollbackFor = Exception.class) 

我的异常处理程序仍然被调用,并相应地写入响应,但事务回滚。

+1

'@ Transactional'会回滚任何未经检查的异常。您只需显式声明检查的异常。 –

+0

我现在意识到,我没有说清楚,我正在使用一个异常处理程序,正如您在此主题中的另一个注释中所述,它是有问题的。我编辑了我的答案,以反映我将这两件事情结合起来解决我的问题。 – michaelgulak

+0

不需要道歉。 'Session#save'不会声明任何已检查的异常,即。它不能抛出任何检查的异常。所以在你的场景中,你必须有其他的东西抛出检查异常,这就是为什么你需要'rollbackFor'。 –