如何从Spring $$ EnhancerBySpringCGLIB $$中捕获异常?
我有和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之前,我真的需要把这张支票放进去吗?这不是让我浪费时间,而是应该能够等待异常吗?
我认为这个行为与事务拦截器有关。如果你把@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(..)来执行)。