繁体   English   中英

让Hibernate在保存时级联,但不能删除?

[英]Getting Hibernate to cascade on save, but not delete?

所以我的hibernate实现有问题。 当我尝试删除父类时,我在级联层次结构深处的类上收到外键约束异常。 在我详细介绍之前,我将首先描述类的关系,因为它与它们如何被保存和删除有关。

在顶层,我有一个Customer类,其中包含一个DefaultMask对象列表。 这是主列表,因为这些默认掩码由我的对象层次结构中的其他类使用,但始终来自此列表。 掩码仅创建到此列表中并从此列表中删除。

在层次结构的下面,我有一个Column类,它可以(可选)在其上设置DefaultMask。 更简洁地描述这种关系;

客户OWNS零到多个DefaultMasks。 客户OWNS零到多列。 列可以有一个DefaultMask。

在我的应用程序中,当我尝试删除Customer时,异常来自Column类的外键约束到DefaultMask类,我相信问题是CascadeType的设置不正确。 我已经研究了这个问题并找到了一个名为mappedBy的属性和使用Hibernate自己的CascadeType.SAVE_UPDATE的信息(为了防止Hibernate试图删除一个Column所持有的DefaultMask),但我承认我在这里有点迷失了使用一些直接指导。 类的相关代码和实际的异常消息如下所示。

顾客:

@Entity
public class Customer {

@Id
private String id;
@OneToMany(cascade = CascadeType.ALL)
private List<DefaultMask> masks;
    //(Columns are held further down in hierarchy)

柱:

@Entity
@Table(name = "WarehouseColumn")
public class Column implements Comparable<Column> {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int hibernateID;
@OneToOne
private DefaultMask mask;

DefaultMask:

@Entity
public class DefaultMask implements Mask {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int hibernateID;
private String type;
private String mask;

异常消息:

org.hibernate.exception.ConstraintViolationException:不能删除或更新父行,外键约束失败( hibernateWarehouseColumn ,约束FK8BB153D994AD57D3外键( mask_hibernateID )参考文献DefaultMaskhibernateID ))产生的原因:com.mysql.jdbc.exceptions。 jdbc4.MySQLIntegrityConstraintViolationException:不能删除或更新父行,外键约束失败( hibernateWarehouseColumn ,约束FK8BB153D994AD57D3外键( mask_hibernateID )引用DefaultMaskhibernateID ))

级联与逻辑所有权的概念密切相关。

基本上,您需要选择以下选项之一:

  • Customer逻辑上拥有其DefaultMask 在这种情况下,您希望在删除Customer时删除DefaultMask ,因此您需要使用CascadeType.ALL 由于Column引用了DefaultMask ,它可能也归Customer所有,应该删除

    它可以通过使用DefaultMaskColumn之间的双向关系以及适当的级联来实现,如下所示:

     @Entity public class DefaultMask implements Mask { @OneToOne(mappedBy = "mask", cascade = CascadeType.ALL) Column column; ... } 
  • DefaultMask是它们自己的实体, Customer只引用现有的DefaultMask 在这种情况下,您可能根本不需要使用级联来实现此关系。

您正急于删除一个客户,该客户会自动删除其默认掩码列表。 但是这些掩码中的一个是由列引用的。 因此数据库(以及Hibernate)拒绝执行删除,因为它会使列处于不一致状态:它将引用不再存在的默认掩码。

所以你有几个功能选择:

  • 保持原样:无法删除客户,因为其中一个掩码仍由列引用
  • 删除级联:删除客户将删除客户但不删除其掩码。
  • 找到引用要删除的用户的任何默认掩码的所有列,并删除这些列。 然后,删除用户及其默认掩码
  • 找到引用要删除的用户的任何默认掩码的所有列,并将其掩码fild设置为null。 然后,删除用户及其默认掩码

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM