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

时间:2011-03-13 21:09:15

标签: jpa cascade one-to-many

我正在尝试删除父级,但我一直收到外键违规。如果我将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;

我的孩子是:病人

我把那个

    @ManyToOne()
    private 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 FOREIGN KEY(docteur_DOCTEUR_ID)参考DocteurDOCTEUR_ID ))

2 个答案:

答案 0 :(得分:6)

您收到外键违规,因为数据库会检查患者表中的每个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

答案 1 :(得分:0)

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

  1. CASCADE:相关行被删除
  2. RESTRICT:删除失败并显示错误
  3. 无操作:像删除一样,但允许触发器先运行,以防他们修复错误
  4. SET NULL:将引用列设置为null(至少一列必须为可空)
  5. SET DEFAULT:将引用列设置为其默认值(然后将引用表中的另一个现有行,除非至少有一个默认值为NULL)