I'm using EJB 3 with Hibernate. I have a stateless session Bean. There is a method deleteItem in that bean.
When a client call the deleteItem method then delete occurred without any problem. But If I'm trying to call the deleteItem method using a for loop and set the limit of that loop 5-10 times then sometimes the delete failed. But not always.
The delete operation actually delete data from 2 tables. The child table and the parent table. Each Delete is committed by performing flush operation.
As I already mentioned that if i execute the delete one by one then no problem happen, it only happen when i try to run it concurrently. The exception I'm getting is below
Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key
constraint fails (`functionTest/MotherTable`, CONSTRAINT `FKBC6CB0E6D5545EFD` FOREIGN KEY
(`MotherTable_FieldId`) REFERENCES `ChildTable` (`childTableId`))
There is no way to happen concurrent delete operation here. And Item delete is not related with other Item delete operation. So if still concurrency happens it will not be a problem for deleting multiple item at the same time.
So, i came to a decision that - "May be the clients are accessing the Same Bean Instance in Multiple Thread" . In such situation two thread keep the same Entity Manager State in different state. One tries to flush the Persistence Context when the other is not yet completed remove of child item. At that point the BatchUpdateException Occured. - It is my observation. I'm not 100% sure about it.
So to overcome this situation I have gone for Optimistic locking. I have created version column in the mother table. Now I'm getting the OptimisticLockException . But I'm not able to catch the exception. Below is the code which I'm using to catch the OptimisticLockException.
private boolean deleteItem(Item itemId) {
Item item= getItem(itemId);
removeChildTableData(item);
mEm.remove(item);
try
{
mEm.flush();
}
catch (OptimisticLockException e)
{
try {
Thread.sleep(1000);
}
catch (InterruptedException e1) {
e1.printStackTrace();
}
deleteItem(itemId);
}
catch(Exception ex)
{
if (ex.getCause() instanceof OptimisticLockException)
{
try {
Thread.sleep(1000);
} catch (InterruptedException x) {
}
deleteItem(itemId);
}
}
return true;
}
So my target is to catch the OptimisticLockException and reExecute the Delete Operation Again. I have checked the Exception Class Name and it is EntityNotFound. But I see that in the stacktrace I'm getting OptimisticLockException as well as StaleObjectStateException.
So, Can anybody please guide me how I should catch this OptimisticLockException ?