【问题标题】:JPA how to remove parent without delete children?JPA如何在不删除子项的情况下删除父项?
【发布时间】:2011-07-14 15:01:08
【问题描述】:

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

我有我的父类:Docteur

//与患者的双向多对一关联 @OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH}, orphanRemoval=false, mappedBy="docteur") 私人名单患者;

我的孩子是:病人

我说的

@ManyToOne() 私人博士;

但就我而言,患者只有一位医生。

在我的经理课上。我尝试了很多没用的东西

这是我的最新版本

倩碧倩碧=读取(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(倩碧); entityManager.persist(倩碧);

这是我得到的错误:

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

【问题讨论】:

    标签: jpa cascade one-to-many


    【解决方案1】:

    因为数据库检查了患者表中的每个 docteur_id 是否引用了有效的医生,所以您会遇到外键违规。这就是外键的重点。该数据库可确保您不会删除患者仍引用的医生。

    为了删除您的docteur,您必须确保数据库中没有其他记录引用此docteur_id。因此,您必须更新此医生的所有患者并将他们的医生 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。

    【讨论】:

    • 对不起,我提到了 Hibernate,也许你正在使用另一个 JPA 实现。不过,答案仍然有效。
    • 如果您必须将Docteur 对象显式设置为null,那么这是否违背了使用JPA 进行cassade 删除的目的?如果是这样的话,那么我认为编写我自己的删除 SQL 更好,并且更多 str8 向前。
    • @Mr.PortStJoe 级联删除会在删除医生时删除医生的患者。 OP 想要删除医生,但将患者留在数据库中,没有医生。这里没有级联。
    • 感谢您的澄清。
    【解决方案2】:

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

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

    【讨论】:

    • 问题是如何在 JPA 2.0 中做到这一点。普通的 SQL 本来很容易。
    猜你喜欢
    • 2012-11-08
    • 2021-05-10
    • 2021-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多