如何从EclipseLink中捕获约束违规异常?

Ala*_*ect 12 jpa eclipselink jpa-2.0

我在我的Web应用程序中使用EclipseLink,我很难优雅地捕获和处理它生成的异常.我从这个线程看到似乎是一个类似的问题,但我没有看到如何解决或修复它.

我的代码看起来像这样:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

当使用违反唯一性约束的实体调用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)
Run Code Online (Sandbox Code Playgroud)

我尝试过以下方法:

    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);            
    }
Run Code Online (Sandbox Code Playgroud)

我意识到使用DataBaseException不可移植,但我需要从某个地方开始.异常永远不会被抓住.有什么建议?

Ala*_*ect 8

看起来我不会再对这个问题进行任何活动了,所以我会发布我的解决方案并将其留在那里.许多网络搜索都找不到任何有用的东西.我本以为这是一本教科书案例,但我找到的教程都没有涵盖它.

事实证明,在这种情况下使用EclipseLink,违反SQL约束时可以捕获的异常是RollBackException,它是em.commit()调用的结果.所以我修改了这样的持久化方法:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

因此调用者捕获EntityExistsException并采取适当的操作.日志仍然填满了内部异常,但可以在以后关闭.

我意识到这有点滥用EntityExistsException的意图,通常仅在重用实体ID字段时使用,但出于用户应用程序的目的,它并不重要.

如果有人有更好的方法,请发布新的答案或评论.