2017-02-09 669 views
0

我有和this人一樣的問題。我得到的堆棧跟蹤,由於這樣的事實,我把那違反了約束的獨特領域的一個新紀錄:

Exception in thread "main" org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement 
at org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:241) 
at org.springframework.orm.hibernate5.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:755) 
at org.springframework.orm.hibernate5.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:594) 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761) 
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730) 
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:504) 
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292) 
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656) 
at sistema.database.manager.BookManager$$EnhancerBySpringCGLIB$$d46d6805.create(<generated>) 
at tests.unatantum.migration.InactiveBookMigration.migrate(InactiveBookMigration.java:53) 
at tests.unatantum.migration.InactiveBookMigration.main(InactiveBookMigration.java:42) 

當我把這個方法(在管理者),它有一個通用的變量T和@Transactional放入整個類,而不是在每一個方法:

public void create(T value) { 
    try{ 
     System.out.println(value); 
     getDao().create(value); 
     System.out.println("good"); 
    } catch (DataIntegrityViolationException dive){ 
     throw new SistemaRuntimeException(dive.getMessage() + ": " + value); 
    } 
} 

System.out.println只是用於調試的原因。
問題是我希望能夠直接在管理器中捕獲該異常。但在堆棧跟蹤中,只有未知類似乎工作。我怎樣才能在管理者中捕獲異常(如果可能的話,採用同樣的方法)?
它似乎拋出異常,當它提交的方法調用所示的一個(這是在同一個經理)的末尾提交。在我打電話給Dao之前,我真的需要把這張支票放進去嗎?這不是讓我浪費時間,而是應該能夠等待異常嗎?

回答

1

我認爲這個行爲與事務攔截器有關。如果你把@Transactional的類,春創建了一個動態代理(經理的子類)和基本調用看起來像

create(t) -> proxy.handle(methodCall) -> open transaction -> call real method (your manager.create(..), where the catch block is) -> commit transaction (this is where the exception happens) -> return result from proxy.create(t)

所以BookManager$$EnhancerBySpringCGLIB$$d46d6805是在此之前和之後,您的方法調用增加了行爲的子類。捕獲發生在你的方法調用中。並且在提交時發生異常。因此,異常發生在代理之外,在你的捕獲之外。 如果你想捕獲這個異常,你需要確保事務在你離開你的catch塊之前被提交(例如,通過在自己的事務中執行dao.create(..)來執行)。