【发布时间】:2014-02-17 06:58:36
【问题描述】:
我有以下代码:
try {
userDAO1.save(userRecord);
userDAO2.save(userRecord);
}
catch(DataIntegrityViolationException e) {
throw new ApplicationException("Contraint violated")
}
userDAO1.save(userRecord) 违反了完整性约束 - 所以在整个代码运行之后,没有任何内容写入 userDAO1 引用的表。
但是,userDAO1.save() 语句不会引发错误/异常 - 因此 userDAO2.save() 也会被执行。
但 DataIntegrityViolationException 被捕获,并且 堆栈跟踪为空。
如何检查 DataIntegrityViolationException 是从哪里引发的,并在 userDAO1.save() 违反约束时阻止执行 userDAO2.save()?
我尝试在此代码周围添加@Transactional 注释,但这也不起作用。
堆栈跟踪:
org.springframework.dao.DataIntegrityViolationException: ORA-00001: unique constraint (UNIQUE_EMAIL) violated
; SQL [n/a]; constraint [UNIQUE_EMAIL]; nested exception is org.hibernate.exception.ConstraintViolationException: ORA-00001: unique constraint (UNIQUE_EMAIL) violated
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:643)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:104)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:516)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy76.updateUser(Unknown Source)
at com.osiris.UserReg.UpdateUserCommand.execute(UpdateUserCommand.java:63)
我贴出来的代码在UpdateUserCommand里面,用@Transactional(rollbackFor=Exception.class, propagation=Propagation.REQUIRES_NEW)注解
【问题讨论】:
-
阅读 save() 或 persist() 或 merge() 或 DAO.save() 方法中调用的任何内容的 javadoc。它不会告诉在调用此方法时执行了插入查询。而且我非常怀疑堆栈跟踪是否为空。将
e.printStackTrace()添加到您的catch 块中,您会看到它。并将 DataIntegrityViolationException 包装在您的 ApplicationException 中。 -
与答案无关,但您是否在服务层捕获
DataIntegrityViolationException异常?查看您的代码,您似乎正在这样做。不是一个好主意。 Service 层与 Dao 层异常无关。 -
我为发布目的简化了代码 - 有一个单独的业务层。 @Nizet - 我添加了一个 printStackStrace(),唯一提到的类是内部 spring 类 - 我没有写任何东西。