I have a problem that I don't understand and I'm hoping someone will help me out.
I'm creating a transaction that creates several records, one of which fails but I'm having problems trapping the error.
Here's the basic sequence
EntityTransaction tx = em.getTransaction();
tx.begin();
//try saving the first record
try {
em.persist(object);
} catch (IllegalStateException ie) {
logger.info("Failed to update " + object + "\n" + ie.getMessage());
} catch (EntityExistsException e) {
throw new SQLException("Object already exists: " + e.getMessage());
} catch (PersistenceException e) {
logger.info("Failed to update " + object + "\n" + e.getMessage());
throw new SQLException("Unable to save record.");
} catch (Exception e) {
logger.info("Failed to persist " + object.toString() + "\n" + e.getMessage());
throw new SQLException("unable to save record");
} finally {
logger.info("worked");
}
// before saving the child record we need to read some other database item
Query q = em.createNamedQuery(query);
try {
result = (Vector<Object>)q.getResultList();
} catch (IllegalStateException ise) {
logger.info("failed state exception"));
result = null;
} catch (IllegalArgumentException iae) {
logger.info("failed arg exception");
result = null;
} catch (DatabaseException dbe) {
logger.info("failed db exception"));
result = null;
} catch (Exception e) {
logger.info("failed exception));
result = null;
} finally {
WeakReference weakResult = new WeakReference(result);
return (Vector<Object>)weakResult.get();
}
// lastly we save the child record
try {
em.persist(object);
} catch (IllegalStateException ie) {
logger.info("Failed to update " + object + "\n" + ie.getMessage());
} catch (EntityExistsException e) {
throw new SQLException("Object already exists: " + e.getMessage());
} catch (PersistenceException e) {
logger.info("Failed to update " + object + "\n" + e.getMessage());
throw new SQLException("Unable to save record.");
} catch (Exception e) {
logger.info("Failed to persist " + object.toString() + "\n" + e.getMessage());
throw new SQLException("unable to save record");
} finally {
logger.info("worked");
}
// then we commit the transaction
try {
EntityTransaction tx = em.getTransaction();
if (tx.getRollbackOnly()) {
tx.rollback();
logger.info("Transaction rolled back");
}
} else {
tx.commit();
}
} catch (PersistenceException e) {
throw new RollbackException(e);
} catch (Exception e) {
e.printStackTrace();
} finally {
em.close(); //close the em after a successful save
}
---------------------------------------------
In a normal situation this works fine. but occasionally the parent record has a bad value that fails due to a duplicate value being created in an index.
when that happens the first persist works fine (even though it shouldn't) and no errors are generated.
The next query however generates an exception as follows:
Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '244' for key 'CLAIMNUMBER'
Error Code: 1062
This has the effect of setting the transaction to rollback only, which is what happens when the final commit takes place.
The second persist doesn't generate any errors at all either.
I would like to trap the error when the record is first persisted but that doesn't seem to happen. What am I missing here?
The log file would look something like this:
worked
failed exception
worked
transaction rolled back