GeeCON Prague 2014*
The moose likes EJB and other Java EE Technologies and the fly likes JMS JPA concurrency issue on Websphere App Server 7, EJB 3.0, OpenJPA EntityExistsException Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » EJB and other Java EE Technologies
Bookmark "JMS JPA concurrency issue on Websphere App Server 7, EJB 3.0, OpenJPA EntityExistsException" Watch "JMS JPA concurrency issue on Websphere App Server 7, EJB 3.0, OpenJPA EntityExistsException" New topic
Author

JMS JPA concurrency issue on Websphere App Server 7, EJB 3.0, OpenJPA EntityExistsException

Sam Nunnally
Greenhorn

Joined: Aug 31, 2012
Posts: 6
Use case is a Device sending JMS messages with GPS info processed by a MDB. If a Device doesnt exist then it is created/inserted and the GPS record created/inserted. Everything works fine when messages are handled as they are sent. The issue occurs when messages from the same device build up and are processed. The process is attempting to insert the Device entity multiple times because at some point the process finds no record exists but the following exception is thrown because the record has been inserted by a previous message being processed. I've tried changing the IsolationLevels to every value up to SERIALIZABLE with no luck. Any ideas would be much appreciated! WAS 7, OpenJPA 2.0.2, EJB3.0

[8/30/12 11:14:01:319 EDT] 0000002a RegisteredSyn E WTRN0074E: Exception caught from before_completion synchronization operation: <openjpa-2.0.2-SNAPSHOT-r422266:1295351 fatal store error> org.apache.openjpa.persistence.EntityExistsException: The transaction has been rolled back. See the nested exceptions for details on the errors that occurred.

Caused by: <openjpa-2.0.2-SNAPSHOT-r422266:1295351 fatal store error> org.apache.openjpa.persistence.EntityExistsException: ORA-00001: unique constraint (SPW_OWN.PK_DEVICE) violated

SSB snippet doing the process:
Device device = deviceManager.findDeviceByDeviceI(deviceString);

if(device == null){
Log.logDebug(this, "device " + deviceString +" is null");

device.setDeviceI(deviceString);

//tried both create and update with no luck
//deviceManager.createDevice(device);

deviceManager.updateDevice(device);
}
JPA SSB:
@Action(Action.ACTION_TYPE.UPDATE)
public String updateDevice(Device device) throws Exception {
EntityManager em = getEntityManager();
try {
device = em.merge(device);
} finally {
em.close();
}
return "";
}

Sam Nunnally
Greenhorn

Joined: Aug 31, 2012
Posts: 6
Doing some testing i have found a decent work around though I'm still not 100% satisfied. Any other suggestions will be welcome:

- Set the JMS MDB in a Bean Managed transaction type and keep the other subsequent SSBs in Container mode so that I can still have the actual data operations Container managed for rollback.
- Set a programmatic threshold in the MDB to retry and process the message X amount of times.
- Catch the EJBTransactionRolledbackException (caused by the EntityExistsException) when the SSB is invoked
- Retry to process the message again using the threshold (in my case the second time was successful because the previous transaction was committed and the retry found that the entity exists and sucessfully processed the message)
- I set my threshold programatically to try and process the message twice before sending it to an error queue.

I don't normally like to use exception catching as a control flow. I also imagine there is a way to keep the JMS MDB as Container Managed transaction and have the J2EE server re-process the message...
 
GeeCON Prague 2014
 
subject: JMS JPA concurrency issue on Websphere App Server 7, EJB 3.0, OpenJPA EntityExistsException