【问题标题】:EclipseLink JPA: remove and persist in the same transaction, constraint errorEclipseLink JPA:删除并保留在同一个事务中,约束错误
【发布时间】:2012-03-13 11:36:39
【问题描述】:

在我的代码中,我在同一个事务中删除并保留对象:

for (final GZAFixInterval actStat : actualStatus) {
        ...
        em.remove(actStat);
        ...
}

for (final Interval newInterval : newIntervals) {
    final GZAFixInterval newGZAfi = new GZAFixInterval();
    ... setters etc
    em.persist(newGZAfi);
}

em.flush();

有时我会收到 PSQLException:错误:冲突的键值违反了排除约束“constraint_name”。这是一个特殊的排除约束。

发生约束错误的情况如下:

  1. em.remove(objectA)
  2. em.persist(objectB)

objectA 和 objectB 必须相互排除在表中存在(这是约束)。在插入 objectB 之前,可能 objectA 并未真正从数据库中删除。

问题是:如果是这种情况,如何强制 JPA 在插入 objectB 之前真正删除 objectA?同花顺解决了吗?

目前我正在使用延迟约束,但欢迎任何想法。

【问题讨论】:

    标签: java jpa eclipselink


    【解决方案1】:

    EclipseLink 不会按照将更改推送到上下文的顺序来处理更改。相反,如果使用更改跟踪,它要么将它们收集到无序列表中,要么在刷新/提交时计算它们。

    Tom 在这里稍微描述了这种行为 http://old.nabble.com/Order-of-operations-in-EclipseLink-td30551198.html 并在此处指向 setShouldPerformDeletesFirst 的文档: http://wiki.eclipse.org/Using_Advanced_Unit_of_Work_API_%28ELUG%29#How_to_Use_the_setShouldPerformDeletesFirst_Method_of_the_Unit_of_Work

    设置这个标志意味着所有的删除都将首先发生,所以如果你想要一个特定的顺序,你需要使用flush。

    【讨论】:

      【解决方案2】:

      flush() 方法将当前事务的更改写入数据库而不终止事务。所以调用flush() 会从数据库中删除objectA。

      然而,我对 JPA 的理解是,它也应该在没有刷新的情况下工作。这就是为什么我不确定冲洗是否能帮助您解决问题。什么时候抛出异常,在提交期间?

      【讨论】:

      • 不,我在显式调用 em.flush() 时遇到错误(正如我的示例最后所说)。
      • 你在remove和persist之间尝试过flush()吗?
      • 我目前正在尝试。现在可能是实际应用程序代码中的错误。 JPA / EclipseLink(用法/错误)只是另一种可能性。谢谢(你的)信息。将使用有关延迟约束应用程序的结果更新我的帖子,并在删除和持久化之间刷新。
      • 我在 remove 和 persist 之间放置了一个 flush(),也推迟了约束。我的错误报告者现在无法重现该错误。我不确定哪一个解决了这个问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-03
      • 2015-09-30
      • 2018-06-27
      • 2013-12-17
      • 2012-01-22
      • 2021-05-07
      • 1970-01-01
      相关资源
      最近更新 更多