2017-02-09 7 views
0

私はthis人と同じ問題があります。私は(マネージャで)このメソッドを呼び出したときに、それは一般的な変数Tを持ち、@Transactional

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) 

:私が原因私はユニークなフィールドのバウンド違反する新しいレコードを入れているという事実に、そのスタックトレースを取得しますない各単一の方法で、クラス全体に置かれた:

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は前とあなたのメソッドの呼び出しの後に動作を追加するサブクラスです。キャッチはあなたのメソッド呼び出しの中で起こります。例外はコミット時に発生します。したがって例外は、キャッチの外側のプロキシ内で発生します。 その例外をキャッチする場合は、キャッチブロックを離れる前にトランザクションがコミットされていることを確認する必要があります(たとえば、dao.create(..)を独自のトランザクションで実行させる)。

関連する問題