Jpa 如何从EclipseLink捕获约束冲突异常?
我在我的web应用程序中使用EclipseLink,很难优雅地捕获和处理它生成的异常。我从一个类似的问题上看出来,但我不知道如何解决或修复它 我的代码如下所示:Jpa 如何从EclipseLink捕获约束冲突异常?,jpa,jpa-2.0,eclipselink,Jpa,Jpa 2.0,Eclipselink,我在我的web应用程序中使用EclipseLink,很难优雅地捕获和处理它生成的异常。我从一个类似的问题上看出来,但我不知道如何解决或修复它 我的代码如下所示: public void persist(Category category) { try { utx.begin(); em.persist(category); utx.commit(); } catch (RollbackException ex) {
public void persist(Category category) {
try {
utx.begin();
em.persist(category);
utx.commit();
} catch (RollbackException ex) {
// Log something
} catch (HeuristicMixedException ex) {
// Log something
} catch (HeuristicRollbackException ex) {
// Log something
} catch (SecurityException ex) {
// Log something
} catch (IllegalStateException ex) {
// Log something
} catch (NotSupportedException ex) {
// Log something
} catch (SystemException ex) {
// Log something
}
}
public void persist(Category category) throws EntityExistsException {
try {
utx.begin();
em.persist(category);
utx.commit();
} catch (RollbackException ex) {
Logger.getLogger(CategoryControl.class.getName()).log(Level.SEVERE, null, ex);
throw new EntityExistsException(ex);
} catch (HeuristicMixedException ex) {
Logger.getLogger(CategoryControl.class.getName()).log(Level.SEVERE, null, ex);
} catch (HeuristicRollbackException ex) {
Logger.getLogger(CategoryControl.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(CategoryControl.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalStateException ex) {
Logger.getLogger(CategoryControl.class.getName()).log(Level.SEVERE, null, ex);
} catch (NotSupportedException ex) {
Logger.getLogger(CategoryControl.class.getName()).log(Level.SEVERE, null, ex);
} catch (SystemException ex) {
Logger.getLogger(CategoryControl.class.getName()).log(Level.SEVERE, null, ex);
}
}
当使用违反唯一性约束的实体调用persist()时,容器会捕获并记录大量异常
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.0.v20110604-r9504):
org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: The statement
was aborted because it would have caused a duplicate key value in a unique or
primary key constraint or unique index identified by 'SQL110911125638570'
defined on 'CATEGORY'.
Error Code: -1
(etc)
我尝试了以下方法:
try {
cc.persist(newCategory);
} catch (PersistenceException eee) {
// Never gets here
System.out.println("MaintCategory.doNewCateogry(): caught: " + eee);
} catch (DatabaseException dbe) {
// Never gets here neither
System.out.println("MaintCategory.doNewCateogry(): caught: " + dbe);
}
我意识到使用DataBaseException是不可移植的,但我需要从某个地方开始。例外情况永远不会被发现。有什么建议吗?EclipseLink应该只抛出persistenceException或RollbackException,具体取决于您在EntityManager上调用的环境和操作顺序。 您的日志记录级别是多少?您可能看到EclipseLink记录了这些异常,但只是作为回滚异常的原因抛出
您可以使用PU属性关闭异常日志记录,但出于诊断目的,通常最好允许EclipseLink记录异常。看起来我不会在这个问题上获得更多的活动,因此我将发布我的工作并将其保留。许多网络搜索都没有找到多少有用的东西。我本以为这是一个教科书案例,但我发现没有一本教程涵盖这一点 在EclipseLink的这种情况下,当违反SQL约束时,可以捕获的异常是RollBackException,这是em.commit()调用的结果。因此,我修改了persist方法,如下所示:
public void persist(Category category) {
try {
utx.begin();
em.persist(category);
utx.commit();
} catch (RollbackException ex) {
// Log something
} catch (HeuristicMixedException ex) {
// Log something
} catch (HeuristicRollbackException ex) {
// Log something
} catch (SecurityException ex) {
// Log something
} catch (IllegalStateException ex) {
// Log something
} catch (NotSupportedException ex) {
// Log something
} catch (SystemException ex) {
// Log something
}
}
public void persist(Category category) throws EntityExistsException {
try {
utx.begin();
em.persist(category);
utx.commit();
} catch (RollbackException ex) {
Logger.getLogger(CategoryControl.class.getName()).log(Level.SEVERE, null, ex);
throw new EntityExistsException(ex);
} catch (HeuristicMixedException ex) {
Logger.getLogger(CategoryControl.class.getName()).log(Level.SEVERE, null, ex);
} catch (HeuristicRollbackException ex) {
Logger.getLogger(CategoryControl.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(CategoryControl.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalStateException ex) {
Logger.getLogger(CategoryControl.class.getName()).log(Level.SEVERE, null, ex);
} catch (NotSupportedException ex) {
Logger.getLogger(CategoryControl.class.getName()).log(Level.SEVERE, null, ex);
} catch (SystemException ex) {
Logger.getLogger(CategoryControl.class.getName()).log(Level.SEVERE, null, ex);
}
}
因此,调用者捕捉到EntityExistsException,并采取适当的操作。日志仍然充满内部异常,但可以稍后关闭
我意识到这有点滥用了EntityExistSexceception的意图,该概念通常仅在重复使用实体ID字段时使用,但对于用户应用程序而言,这并不重要
如果有人有更好的方法,请发表新的答案或评论。我使用的是Spring Boot 1.1.9+EclipseLink 2.5.2。这是捕获ConstraintViolationException的唯一方法。请注意,my
handleError(ConstraintViolationException)
是一个非常简单的实现,它只返回找到的第一个冲突
注意,当我切换到Hibernate 4.3.7和Hibernate Validator 5.1.3时,这段代码也是必需的
似乎将PersistenceExceptionTranslationPostProcessor exceptionTranslation()
添加到我的persistenceJavaConfig类中也没有效果
import javax.persistence.RollbackException;
导入javax.validation.ConstraintViolation;
导入javax.validation.ConstraintViolationException;
导入org.springframework.http.HttpStatus;
导入org.springframework.http.ResponseEntity;
导入org.springframework.transaction.TransactionSystemException;
导入org.springframework.web.bind.annotation.ControllerAdvice;
导入org.springframework.web.bind.annotation.ExceptionHandler;
@控制器建议
类GlobalExceptionHandler
{
@ExceptionHandler(TransactionSystemException.class)
公共响应处理错误(最终交易系统例外tse)
{
if(tse.getCause()!=null&&tse.getCause()回滚异常实例)
{
最终回滚异常re=(回滚异常)tse.getCause();
if(re.getCause()!=null&&re.getCause()instanceof ConstraintViolationException)
{
返回handleError((ConstraintViolationException)re.getCause());
}
}
掷骰子;
}
@ExceptionHandler(ConstraintViolationException.class)
@抑制警告(“未使用”)
公共责任处理错误(最终约束例外cve)
{
对于(final constraintviolations v:cve.getConstraintViolations())
{
返回新的响应属性(新对象()
{
公共字符串getErrorCode()
{
返回“验证错误”;
}
公共字符串getMessage()
{
返回v.getMessage();
}
},HttpStatus.BAD_请求);
}
投掷cve;
}
}
我用这个
if (!ejbGuardia.findByPkCompuestaSiExiste(bean.getSipreTmpGuardiaPK())) {
ejbGuardia.persist(bean);
showMessage(ConstantesUtil.MENSAJE_RESPUESTA_CORRECTA, SEVERITY_INFO);
} else {
showMessage("Excel : El registro ya existe. (" + bean.toString() + ") ", SEVERITY_ERROR);
}
我的职能是:
public boolean findByPkCompuestaSiExiste(Object clasePkHija) throws ClassNotFoundException {
if (null != em.find(this.clazz, clasePkHija)) {
return true;
}
return false;
}
因此,我不需要为每个Persist编写验证程序,它在my DAO类中很常见。编辑persistence.xml并添加以下属性: property name=“eclipselink.exception handler”value=“your.own.package.path.YourOwnExceptionHandler” 现在创建类YourOwnExceptionHandler(在正确的包上)。它需要实现org.eclipse.persistence.exceptions.ExceptionHandler 创建一个非参数构造函数和所需的方法handleException(…)
在这个方法中,您可以捕获异常 2019-12-18 由于这是一个被广泛接受的问题,而且我刚刚遇到了一个与
EclipseLink
非常相似的问题,在Maven
多模块web应用程序中,运行在Weblogic 12c
服务器上,使用JTA
,我将在这里发布我的解决方案,希望为某人节省几个小时
在persistence.xml
中,我们有:
< property name="eclipselink.persistence-context.flush-mode"
value="commit" />
相关伪代码:
try {
repository.update(entity);
repository.getEntityManager().flush();
} catch (Exception e ) {
log.info(e.toString());
...
}
正如您所说,我希望在开发模式期间保持登录,以便在系统错误发生时能够捕获它们。但真正的问题是,当我调用commit()方法时,我似乎无法捕获异常,因此我可以在屏幕上抛出一条消息。“DataBaseException不可移植”是什么意思?谢谢@DataBaseException类是由org.eclipse定义的,而不是JPA规范。所以这个李