我的应用程序使用JPA + JavaDB,当我尝试持久化违反约束的对象时,我在控制台上获得SQLIntegrityConstraintViolationException。
那没关系,但是我无法抓住那个例外,为什么?
这是我的代码示例,我想捕获异常。如果我查看documentation of persist(),则没有SQLIntegrityConstraintViolationException的迹象。
em.getTransaction().begin();
em.persist(object);
em.getTransaction().commit();
控制台堆栈跟踪的一部分:
[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)
...
答案 0 :(得分:3)
日志告诉你原因。 SQLIntegrityConstraintViolationException
包含在org.eclipse.persistence.exceptions.DatabaseException
内。您可以捕获此异常并对SQLIntegrityConstraintViolationException
不知道你的代码,不可能告诉你在哪里改变代码,但是如果你想真正抓住SQLIntegrityConstraintViolationException
,你必须在它被另一个异常包裹之前这样做。
答案 1 :(得分:0)
2019-12-18
在EclipseLink
服务器上运行并使用Maven
的{{1}}多模块Web应用程序中,Weblogic 12c
的问题非常相似。
在JTA
中,我们有:
persistence.xml
就我而言。我必须在< property name="eclipselink.persistence-context.flush-mode"
value="commit" />
上手动调用flush()
来强制刷新,并在适当的时间和行(通常在EntityManager
中发生异常)才能捕获并处理它。
我的插入/更新/删除查询位于我的JPA提供程序缓存中,没有发送到数据库,因此不会发生此异常,因此代码无法捕获它。
自动将其清除,并且异常将发生在事务边界的末尾,在我的情况下,基本上发生在方法的末尾,这显然在我的try block
块之后,所以我无法捕捉到它。
日志中最后捕获到的异常(我屏蔽了一些不相关的信息):
try{...}catch(Exception e){...}
相关的伪代码:
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
答案 2 :(得分:0)
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());
}
}