【问题标题】:Catching constraint violations in JPA 2.0在 JPA 2.0 中捕获约束违规
【发布时间】:2023-03-30 21:06:01
【问题描述】:

考虑以下实体类,例如与 EclipseLink 2.0.2 一起使用 - 其中link 属性不是主键,但它是唯一的。

@Entity
public class Profile {  
  @Id 
  private Long id;

  @Column(unique = true)
  private String link;

  // Some more attributes and getter and setter methods
}

当我为 link 属性插入具有重复值的记录时,EclipseLink 不会抛出 EntityExistsException,而是抛出 DatabaseException,并显示消息说明违反了唯一约束。

这似乎不是很有用,因为没有一种简单的、独立于数据库的方法来捕获这个异常。处理此问题的建议方法是什么?

我考虑过的几件事是:

  • 检查DatabaseException 上的错误代码 - 不过,我担心这个错误代码是数据库的本机错误代码;
  • 事先使用link 的特定值检查Profile 的存在 - 这显然会导致大量多余的查询。

【问题讨论】:

标签: java jpa try-catch eclipselink unique-constraint


【解决方案1】:

当我为链接属性插入具有重复值的记录时,EclipseLink 不会抛出 EntityExistsException

是的,JPA 提供程序不应该在这种情况下抛出 EntityExistException,除了主键之外,您不会得到 EntityExistException

(...) 但会引发 DatabaseException,并显示消息说明违反了唯一约束。

这是来自 EclipseLink 的非常错误,JPA 提供程序应该抛出 PersistenceException 或子类,但肯定不是像 o.e.p.e.DatabaseException 这样的特定异常。这是一个错误,应该像我在previous answer 中提到的那样报告。

这似乎不是很有用,因为没有一种简单的、独立于数据库的方法来捕获这个异常。处理此问题的建议方法是什么?

和上面的答案一样,看我的previous answer

【讨论】:

  • 既然您在这里特别提到了 EclipseLink:您知道其他行为正确的 JPA 提供商吗?
  • @Hank 也许这个问题在最近的版本中已经修复了,不能说。但据我所知,在这种情况下,Hibernate 确实抛出了 PersistenceException
【解决方案2】:

太糟糕了,他们在 JPA 中没有 ConstraintViolationException。我创建了一个辅助方法来确定 PersistenceException 是否是给定类的约束冲突——尽管它只是休眠状态。我想有一种方法可以使用其他实现。

protected Boolean isUniqueConstraintViolation(PersistenceException ex, Class entity) {

    if (((NonUniqueObjectException)ex.getCause()).getEntityName().equals(entity.getName())) {
        return true;
    }

    return false;
}

【讨论】:

    猜你喜欢
    • 2019-04-08
    • 1970-01-01
    • 2013-11-27
    • 2016-06-05
    • 2015-09-02
    • 1970-01-01
    • 2014-11-29
    • 2020-03-28
    • 1970-01-01
    相关资源
    最近更新 更多