JPA如何删除父级而不删除子级?

发布于 2024-10-21 21:30:39 字数 1036 浏览 1 评论 0原文

我正在尝试删除父级,但我不断收到外键违规问题。如果我将 Cascade.ALL 放在父级中,它也会删除子级。现在这就是我想要的。

我有我的父类:Docteur

//bi-directional many-to-one association to Patient
    @OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH}, orphanRemoval=false, mappedBy="docteur")
    private List patients;

,我的孩子是:Patient

我这么说

    @ManyToOne()
    private Docteur docteur;

,但就我而言,病人只有一个Docteur。

在我的经理课上。我尝试了很多在这里不起作用的东西

我的最新版本

Clinique clinique = read(clinique_ID);
Docteur docteur = entityManager.createNamedQuery("getDocteur", Docteur.class).setParameter("clinique_ID", clinique_ID).setParameter("docteur_ID", docteur_ID).getSingleResult();

clinique.getDocteurs().remove(docteur);

entityManager.merge(clinique);

entityManager.persist(clinique);

这是我得到的错误:

无法删除或更新父行:外键约束失败(jerabi_asteriskdb/Patient,CONSTRAINT FK340C82E5A10F077E 外键 (docteur_DOCTEUR_ID) 参考 Docteur (DOCTEUR_ID))

I'm trying to remove a parent, but I keep getting a Foreign Key violation. If I put Cascade.ALL in the parent, it delete the children too. And it's now what I want.

I have my parent class : Docteur

//bi-directional many-to-one association to Patient
    @OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH}, orphanRemoval=false, mappedBy="docteur")
    private List patients;

and my children are : Patient

I put that

    @ManyToOne()
    private Docteur docteur;

but in my case, the patient choul only have one Docteur.

In my Manager class. I try lot of things that didn't work

here my latest version

Clinique clinique = read(clinique_ID);
Docteur docteur = entityManager.createNamedQuery("getDocteur", Docteur.class).setParameter("clinique_ID", clinique_ID).setParameter("docteur_ID", docteur_ID).getSingleResult();

clinique.getDocteurs().remove(docteur);

entityManager.merge(clinique);

entityManager.persist(clinique);

Here the error that I get :

Cannot delete or update a parent row: a foreign key constraint fails (jerabi_asteriskdb/Patient, CONSTRAINT FK340C82E5A10F077E FOREIGN KEY (docteur_DOCTEUR_ID) REFERENCES Docteur (DOCTEUR_ID))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最好是你 2024-10-28 21:30:39

您会遇到外键违规,因为数据库会检查患者表中的每个 docteur_id 是否引用有效的 docteur。这就是外键的全部意义。该数据库确保您不会删除仍被患者引用的医生。

为了删除您的 docteur,您必须确保数据库中没有其他记录引用此 docteur_id。因此,您必须更新该 docteur 的所有患者并将其 docteur_id 设置为 null :

Docteur docteur = entityManager.createNamedQuery("getDocteur", Docteur.class).setParameter("clinique_ID", clinique_ID).setParameter("docteur_ID", docteur_ID).getSingleResult();

for (Patient patient : docteur.getPatients()) {
    patient.setDocteur(null);
}
docteur.patients.clear();
clinique.getDocteurs().remove(docteur);

此外,所有附加(持久)实体都会由 Hibernate 自动更新。没有必要坚持和合并它们。阅读 http://docs.jboss.org /hibernate/core/3.6/reference/en-US/html_single/#objectstate-overview

You get a foreign key violation because the database checks that every docteur_id in the patient table refers to a valid docteur. This is the whole point of foreign keys. The database ensures that you don't delete a docteur still referenced by patients.

In order to delete your docteur, you must ensure that no other record in the database references this docteur_id. So, you must update all the patients of this docteur and set their docteur_id to null :

Docteur docteur = entityManager.createNamedQuery("getDocteur", Docteur.class).setParameter("clinique_ID", clinique_ID).setParameter("docteur_ID", docteur_ID).getSingleResult();

for (Patient patient : docteur.getPatients()) {
    patient.setDocteur(null);
}
docteur.patients.clear();
clinique.getDocteurs().remove(docteur);

Also, all the attached (persistent) entities are automatically updated by Hibernate. There is no need to persist and merge them. Read http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#objectstate-overview.

无声情话 2024-10-28 21:30:39

为了使关系数据库能够强制数据完整性,必须考虑对引用表中的依赖行的引用。 SQL 2003 指定了 5 种不同的引用操作:

  1. CASCADE:从属行被删除
  2. RESTRICT:删除失败并出现错误
  3. NO ACTION:与删除类似,但允许触发器首先运行,以防它们修复错误
  4. SET NULL:将引用列设置为 null (至少有一列必须可为空)
  5. SET DEFAULT:将引用列设置为其默认值(然后将引用表中的另一现有行,除非至少有一个默认值为 NULL)

So that a relation database can enforce data integrity, references to dependent rows in referencing tables have to be considered. SQL 2003 specifies 5 different referential actions:

  1. CASCADE: dependent rows get deleted
  2. RESTRICT: delete fails with an error
  3. NO ACTION: like delete, but allows triggers to run first, in case they fix the error
  4. SET NULL: sets the referencing columns to null (at least one column must be nullable)
  5. SET DEFAULT: sets the referencing columns to their default value (which will then reference another existing row in the table, unless at least one default is NULL)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文