Issue 1:
Dmitry V. Zemnitskiy opened SPR-3849 and commented

Copied from http://forum.springframework.org/showthread.php?p=140845

Also see http://forum.springframework.org/showthread.php?t=31531

I just checked with latest available spring (2.0.6), hibernate (3.2.5), hibernate entity manager and MS SQL database (both MSDE and MS SQL Server 2000), jtds driver.

As I see it is still not solved, that is, with declarative transactions and exception translation, having business manager class annotated with @Repository and business method annotated with @Transactional (no nested transactions), example configuration below:

Code:

<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="${jpa.persistence.unit}" />
<property name="jpaVendorAdapter" ref="hibernateAdapter" />
</bean>

<bean name="hibernateAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />

<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"
ref="entityManagerFactory" />

</bean>

<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

<bean
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

<bean id="entityManager"
class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory"
ref="entityManagerFactory" />
</bean>

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

I get UnexpectedRollbackException caused by integrity violation exception, because actual database operation and constraints verification are seems deferred to commit() in MS SQL (much like in Oracle I think).

Here's exception stack trace:

Code:

org.springframework.transaction.UnexpectedRollbackException: JPA transaction unexpectedly rolled back (maybe marked rollback-only after a failed operation); nested exception is javax.persistence.RollbackException: Error while commiting the transaction

Caused by:

javax.persistence.RollbackException: Error while commiting the transaction

at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:71)

at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:433)

at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:662)

at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:632)

at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:314)

at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:117)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)

at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)

at $Proxy34.handleChangeMsisdn(Unknown Source)

at com.vyke.mobile.server.io.ConnectionHandlerImpl.packetReceived(ConnectionHandlerImpl.java:254)

... removed application code calls ...

at java.lang.Thread.run(Unknown Source)

Caused by: org.hibernate.exception.ConstraintViolationException: could not update: [com.vyke.mobile.server.domain.Client#4]

at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)

at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)

at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2425)

at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2307)

at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2607)

at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:92)

at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)

at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)

at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:142)

at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)

at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)

at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)

at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)

at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)

at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:54)

... 29 more

Caused by: java.sql.SQLException: Violation of UNIQUE KEY constraint 'UQ__Client__72C60C4A'. Cannot insert duplicate key in object 'Client'.

at net.sourceforge.jtds.jdbc.SQLDiagnostic.addDiagnostic(SQLDiagnostic.java:365)

at net.sourceforge.jtds.jdbc.TdsCore.tdsErrorToken(TdsCore.java:2781)

at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2224)

at net.sourceforge.jtds.jdbc.TdsCore.getMoreResults(TdsCore.java:628)

at net.sourceforge.jtds.jdbc.JtdsStatement.processResults(JtdsStatement.java:525)

at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQL(JtdsStatement.java:487)

at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeUpdate(JtdsPreparedStatement.java:421)

at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:23)

at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2403)

... 41 more

I found very similar problem description here :

http://forum.springframework.org/showthread.php?t=31531

it is dated by last year..

I was able to solve the problem only by verification during business method invocation if conflicting record already exists in database using extra select statement.

IMO it is very rough solution and quite bad problem in Spring, as the situation is quite common and it voids all efforts made to improve persistence exception

handling in Spring at all.

Regards,

Dima

Affects: 2.0.5, 2.0.6, 2.1 M3

Issue 2:
Dmitriy Kopylenko opened SPR-163 and commented

There is a notion of Errors <<interface>>, so during validation there might be some property values rejected. We treat Errors as critical e.g. in Controllers after validation we check Errors collection and if not empty we DO NOT proceed (invoke the middle tier). There are some use cases however that state - some validations should be treated as WARNINGS e.g. if the rule is not satisfied, just display a warning message to the user, but still proceed with the workflow.

I'm not sure if that's been solved already, but in any case, would be nice to create a Warnings <<interface>> to distinguish between those to concepts (Errors -> do not proceed, Warnings -> still proceed)

Dmitriy.

Affects: 1.1 RC1

Issue Links:

#6123 Expand Errors object to be a Messages object ("is duplicated by")

22 votes, 15 watchers