删除子级后,JPA关系未更新 [英] JPA relationship not getting updated when children are removed

查看:103
本文介绍了删除子级后,JPA关系未更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下情况:

@Entity
public class A {
  @OneToMany(mappedBy = "a", cascade = CascadeType.ALL)
  private List<B> bList;
}

@Entity
public class B {
  @ManyToOne()
  @JoinColumn(name = "a_id", referencedColumnName = "id")
  private A a;

  @ManyToOne()
  @JoinColumn(name = "c_id", referencedColumnName = "id")
  private C c;
}

@Entity
public class C {
  @OneToMany(mappedBy="c", cascade=CascadeType.ALL, orphanRemoval=true)
  @CascadeOnDelete // eclipselink specific optimization annotation
  private List<B> bList;
}

换句话说:对象A和对象C都包含许多B对象

In other words: both object A and object C contains a number of B objects.

当我删除一个C对象时(从技术上讲,我正在更新包含几个C对象的对象并使用orphanremoval),我希望删除所有引用的B对象。使用当前注释可以正常工作。但是,实体管理器似乎并不了解位于其缓存中的对象A现在失去了一些子代。如果我有一个A的实例,我当然必须手动更新它的bList,或者做一个新的查询来更新它,但是即使是新获取的A对象仍然过时。重申一下:

When I remove a C object (technically, I am updating an object containing several C objects and using orphanremoval), I wish to remove all referenced B-objects, which works as expected with current annotations. However, the Entity manager doesn't seem to understand that object A lying in its cache now have lost some children. If I had an instance of A, I would of course have to update its bList manually, or do a new query to update it, but even newly fetched A-objects are still outdated. To reiterate:


  • C个对象被删除。

  • 删除操作通过orphanRemoval级联为B个对象。

  • b在实体管理器中缓存的对象中的列表未更新

  • 手动清除实体管理器的缓存使其可以正确检索更新的对象。

  • C objects are removed.
  • Removal is cascaded to B objects with orphanRemoval.
  • bList in A objects cached in Entity Manager is not updated.
  • Manually purging Entity Managers cache makes it retrieve properly updated objects.

如何解决?我希望实体管理器自动更新其持久性上下文,或者在@JoinColumn上提供级联批注,但在这里似乎都不是。

How can this be solved? I would expect either the entity managers to update its persistence context automatically, or making a cascade annotation available on @JoinColumn, but neither seems to be the case here.

编辑:似乎问题出在对象A的bList更新时对象C的bList没有更新(因此无法级联更改)。我不知道为什么。仍然注意,我在说的是持久性上下文,而不是实例化的对象。

推荐答案

JPA不会为您维护关系,应用程序必须维护它们。这意味着,无论何时删除实体,应用程序都有责任清理对该实体的所有引用。当它是外键关系时很明显,因为如果不这样做,数据库约束通常将导致异常。在反向引用的情况下,尽管关系没有严格的数据库约束,但用户通常会错误地认为JPA会处理它-导致缓存损坏。

JPA does not do relationship maintenence for you, the application must maintain them. That means when ever you delete an entity, the application is responsible for cleaning up any references to that entity. It is obvious when it is a foreign key relationship, as database constraints will usually cause an exception if it is not done. In the case of back references though where the relationship does not have a strict database constraint, users generally mistakenly believe that JPA will handle it - leaving the cache corrupted.

处理该问题的方法是删除对C和B实体的任何引用。在您的对象模型中,这意味着修复A的bList以删除B。我已经看到这是通过实体删除事件或在应用程序代码中处理的。由于在这种情况下,A没有外键,因此您也可以在删除发生后(即在刷新或提交之后)从数据库刷新受影响的A实体。

The way to handle it is to remove any references to C and B entities. In your object model, that means fixing A's bList to remove Bs. I have seen this handled through entity remove events or in application code. Since in this case, A does not have a foreign key, you could also refresh the affected A entities from the database after the delete has occured (ie after a flush or commit).

这篇关于删除子级后,JPA关系未更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆