In my application it's very likely that two entity beans with the same primary key (consisting of a string) get persisted at the same time. If that happens a "duplicate key" exception (PersistenceException/NonUniqueObjectException) is raised and the the current transaction is unfortuantely being rolled back.
The problem is that it does not seem to be possible to recover from this error gracefully. Trying to catch the exception nevertheless rolls back the transaction. I have read, that's because it's an SystemException and that those kind of RuntimeExceptinons always roll back the current transaction.
I have also read that, if we declare those RuntimeExceptions as application exceptions in the ejb-jar xml description and set the rollback tag to false, the current transaction is not being rolled back. I have tried this by inserting the following xml into my ejb-jar, but it does not prevent the transaction from being rolled back:
<ejb-jar> <assembly-descriptor> <interceptor-binding> <ejb-name>*</ejb-name> <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class> </interceptor-binding> <application-exception> <exception-class>org.hibernate.NonUniqueObjectException</exception-class> <rollback>false</rollback> </application-exception> <application-exception> <exception-class>javax.persistence.PersistenceException</exception-class> <rollback>false</rollback> </application-exception> </assembly-descriptor> </ejb-jar>
My application heavily depends on gracefully dealing with those kind of duplicate key exceptions, because I need them to figure out, whether or not a certain entity already exists and I can't use a simple SELECT to find out, because of concurrency issues and I can't use an isolation level of Serializable, because of performance reasons.
How can I make sure that I catch those kind of duplicate key exceptions without the current transaction being rolled back when I call entityManager.persit(myEntityBean) ???
PS: This guy seems to have the same problem