首页 > 解决方案 > 更新子实体但保存父实体会导致 ObjectOptimisticLockingFailureException

问题描述

我有一个这样的实体:

class Parent {
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private List<ChildUpdatedByBatch> childrenUpdatedByBatch;
    @OneToOne(mappedBy = "parent", cascade = CascadeType.ALL)
    private Child child;
....
}

我有一个批处理作业,最终保存/更新一个子实体(ChildUpdatedByBatch),以及一个更新子实体的常规操作。

问题是我们使用parentRepository来更新两个实体,因此批处理作业具有以下内容:

// updating parent entity by adding/ or updating a ChildUpdatedByBatch
parentRepository.save(parent);

并且常规动作还使用:

// updating parent entity by adding/ or updating the Child entity
parentRepository.save(parent);

但是第二个,(常规动作),它抛出 ObjectOptimisticLockingFailureException 因为

Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [<package>.ChildEntityUpdatedByBatch#911].

我想知道,如果为每个子实体创建存储库可以解决问题。我的意思是,有类似的东西:

child.save(child) // with child having a reference to out-of-date parent

或者,如果这也不能解决问题。

标签: javaspringspring-bootjpaoptimistic-locking

解决方案


为自身添加存储库Child当然是可取的,但我怀疑它会解决你的问题。

你仍然需要用孩子更新父母,所以parentRepository.save(parent);如果我正确理解你的情况,你仍然会有两个动作。所以无论如何你最终都会得到一个OptimisticLockException

我会简单地应用处理这种异常的一般程序,即:

  • 赶上OptimisticLockException
  • 合并发生保存异常的实体
  • 再次重试持久化/更新

推荐阅读