Skip to content

Flush exception translation not working anymore with Hibernate 5.2 [SPR-14457] #19026

Closed
@spring-projects-issues

Description

@spring-projects-issues

Will Darby opened SPR-14457 and commented

I am porting from Spring 3.2+Hibernate 4.1 to Spring 4.3+Hibernate 5.2. There appears to be an issue with Aspect ordering between aspects detected using annotations and those added manually with Advised.addAdvisor(). More specifically, advisors added with Advised.addAdvisor() are added after those discovered using annotations unless 'beforeExistingAdvisors' is added, in which case it is before all others.

The problem arises when using annotation-based transactions, i.e.,

<tx:annotation-driven transaction-manager="transactionManager" order="10"/>

in combination with org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor.

The PersistenceExceptionTranslationPostProcessor adds the Aspect using Advised.addAdvisor() after the BeanFactoryTransactionAttributeSourceAdvisor. The result is that when the a transaction completes and flushes cached operations to the database, exceptions that arise are not processed by the PersistenceExceptionTranslator since it has already completed. The result is that Hibernate exceptions are not translated into Spring exceptions for database operations that occur during commit.

This was working correctly in the previous versions (Spring 3.2+Hibernate 4.1). I have tried adding 'order' to the PersistenceExceptionTranslationPostProcessor, but it is has no effect.

Below are two stack traces illustrating the issue.
The first shows that the PersistenceExceptionTranslator is invoked within the TransactionInterceptor:
PersistenceExceptionTranslationInterceptor.invoke(MethodInvocation) line: 136 ReflectiveMethodInvocation.proceed() line: 179 TransactionInterceptor$1.proceedWithInvocation() line: 99 TransactionInterceptor(TransactionAspectSupport).invokeWithinTransaction(Method, Class, InvocationCallback) line: 281
TransactionInterceptor.invoke(MethodInvocation) line: 96
ReflectiveMethodInvocation.proceed() line: 179
AspectJAfterThrowingAdvice.invoke(MethodInvocation) line: 62
ReflectiveMethodInvocation.proceed() line: 168
ExposeInvocationInterceptor.invoke(MethodInvocation) line: 92 ReflectiveMethodInvocation.proceed() line: 179
JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 213 $Proxy48.storeAnalysisRule(String, AnalysisRule) line: not available
AnalysisRuleTest.duplicateSaveError() line: 71

The second shows that the exception is occurring during the flush() operation, after the PersistenceExceptionTranslator has completed:
Stacktrace was: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute batch at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:147) at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155) at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:162) at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1403) at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:473) at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3133) at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2370) at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:467) at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:146) at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38) at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:220) at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:68) at org.springframework.orm.hibernate5.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:581) 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:485) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) at com.sun.proxy.$Proxy48.storeAnalysisRule(Unknown Source) at test.com.leeriver.trading.account.AnalysisRuleTest.duplicateSaveError(AnalysisRuleTest.java:71) Caused by: org.hibernate.exception.ConstraintViolationException: could not execute batch at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:112) at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111) at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.performExecution(BatchingBatch.java:119) at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.doExecuteBatch(BatchingBatch.java:97) at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.execute(AbstractBatchImpl.java:147) at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.executeBatch(JdbcCoordinatorImpl.java:206) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:611) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:456) at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337) at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1397) ... 53 more Caused by: java.sql.BatchUpdateException: integrity constraint violation: unique constraint or index violation; USER_RULE_IDX table: USERANALYSISRULE at org.hsqldb.jdbc.JDBCPreparedStatement.executeBatch(Unknown Source) at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297) at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297) at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297) at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.performExecution(BatchingBatch.java:110) ... 61 more


Affects: 4.3.1

Issue Links:

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)in: dataIssues in data modules (jdbc, orm, oxm, tx)type: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions