2012-12-07 52 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'。 –