|
I'm not sure how the 'setRollbackOnly' could be avoided without violating the JPA spec requirement for that to happen when a RuntimeException is thrown by a method of the EntityManager.
From the JPA 2.1 spec section 3.1.1 EntityManager Interface (I'm only pasting a little for this part since its too long):
Runtime exceptions thrown by the methods of the EntityManager interface other than the LockTimeoutException will cause the current transaction to be marked for rollback if the persistence context is joined to that transaction.
JPA 2.1 spec section 7.9.2 Provider Responsibilities (note the fifth requirement is about this case):
The Provider has no knowledge of the distinction between transaction-scoped and extended persistence contexts. It provides entity managers to the container when requested and registers for transaction synchronization notifications.
-
When EntityManagerFactory.createEntityManager is invoked, the provider must create and return a new entity manager. If a JTA transaction is active and the persistence context is of type SynchronizationType.SYNCHRONIZED, the provider must register for synchronization notifications against the JTA transaction.
-
When EntityManager.joinTransaction is invoked, the provider must register for synchronization notifications against the current JTA transaction if a previous joinTransaction invocation for the transaction has not already been processed.
-
When the JTA transaction commits, if the persistence context is of type SynchronizationType.SYNCHRONIZED or has otherwise been joined to the transaction, the provider must flush all modified entity state to the database.
-
When the JTA transaction rolls back, the provider must detach all managed entities if the persistence context is of type SynchronizationType.SYNCHRONIZED or has otherwise been joined to the transaction. Note that the JTA transaction may rollback in a background thread (e.g., as a result of transaction timeout), in which case the provider should arrange for the managed entities to be detached from the persistence context but not concurrently while the application is in an EntityManager invocation.
-
When the provider throws an exception defined to cause transaction rollback, the provider must mark the transaction for rollback if the persistence context is of type SynchronizationType.SYNCHRONIZED or has otherwise been joined to the transaction.
-
When EntityManager.close is invoked, the provider should release all resources that it may have allocated after any outstanding transactions involving the entity manager have completed. If the entity manager was already in a closed state, the provider must throw the IllegalStateException.
-
When EntityManager.clear is invoked, the provider must detach all managed entities.
I'm not sure that the suppressed error suggestion would help as I think the caller needs to call the getSuppressed() method.
|