Reputation: 6372
My application uses JPA+JavaDB and when I try to persist an object that violates a constraint I get SQLIntegrityConstraintViolationException on console.
That is OK but I can't catch that exception, why?
This is a sample of my code where I would like to catch the exception. If I look at the documentation of persist(), there is no sign of SQLIntegrityConstraintViolationException.
em.getTransaction().begin();
em.persist(object);
em.getTransaction().commit();
Part of the console stack trace:
[EL Warning]: 2013-09-15 16:38:57.571--UnitOfWork(459929151)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: A instrução foi interrompida, porque iria gerar um valor duplicado da chave em uma restrição de chave primária ou de unicidade identificada por 'SQL130819202336721' definida em 'CORRETORA'.
Error Code: -1
Call: UPDATE CORRETORA SET NOME = ? WHERE (ID = ?)
bind => [2 parameters bound]
Query: UpdateObjectQuery(Corretora[ id=7 ])
javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: A instrução foi interrompida, porque iria gerar um valor duplicado da chave em uma restrição de chave primária ou de unicidade identificada por 'SQL130819202336721' definida em 'CORRETORA'.
Error Code: -1
Call: UPDATE CORRETORA SET NOME = ? WHERE (ID = ?)
bind => [2 parameters bound]
Query: UpdateObjectQuery(Corretora[ id=7 ])
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:157)
at br.meuspila.util.AbstractCrud.persist(AbstractCrud.java:50)
at br.meuspila.corretora.CorretoraRN.persist(CorretoraRN.java:30)
at br.meuspila.javafx.EditarCorretoraController$1.handle(EditarCorretoraController.java:66)
at br.meuspila.javafx.EditarCorretoraController$1.handle(EditarCorretoraController.java:51)
...
Upvotes: 8
Views: 19445
Reputation: 1124
try{
em.getTransaction().begin();
em.persist(object);
em.getTransaction().commit();
} catch (Exception e) {
if(e.getCause() != null && e.getCause().getCause() instanceof SQLIntegrityConstraintViolationException) {
SQLIntegrityConstraintViolationException sql_violation_exception = (SQLIntegrityConstraintViolationException) e.getCause().getCause() ;
log.error("SQLIntegrityConstraintViolationException has accured. " + sql_violation_exception.getMessage());
} else {
log.error(e.getMessage());
}
}
Upvotes: -2
Reputation: 1269
2019-12-18
I just had a very similar issue with EclipseLink
, in a Maven
multi module web application running on Weblogic 12c
server and using JTA
.
In the persistence.xml
we are having:
< property name="eclipselink.persistence-context.flush-mode"
value="commit" />
In my case. I had to manually call flush()
on EntityManager
to force flush and the exception to occur at proper time and line (basically in the try block
) to be able to catch it, handle it.
My insert/update/delete query was sitting in my JPA provider cache, and not sent to the database, this exception couldn't occur so the code couldn't caught it.
Automatically, it would have been flushed and the exception would have occured at the end of the transaction boundary, basically at the end of the method in my case, which is obviously far after my try{...}catch(Exception e){...}
block, so I was not able to catch it.
The final caught exception in the log (I have masked some not related info):
javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - x.x.x.v00000000-0000000): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (XXXXX.UNIQUE_KEY_NAME) violated
Related pseudo code:
try {
repository.update(entity);
repository.getEntityManager().flush();
} catch (Exception e ) {
log.info(e.toString());
...
}
Upvotes: 0
Reputation: 280172
The log is telling you why. The SQLIntegrityConstraintViolationException
is wrapped inside an org.eclipse.persistence.exceptions.DatabaseException
. You can catch this exception and do something about the SQLIntegrityConstraintViolationException
Not knowing your code, it's impossible to tell you where to change it, but if you wanted to really catch SQLIntegrityConstraintViolationException
, you would have to do so before it got wrapped in the other exception.
Upvotes: 5