休眠:级联删除一对多关系的问题

时间:2019-03-10 13:53:49

标签: sql hibernate hibernate-cascade

我有以下实体模型。

@Entity
@Table(name="product")
public class ProductEntity {
      @Id
      @GeneratedValue(generator = "uuid2")
      @GenericGenerator(name = "uuid2", strategy = "uuid2")
      private UUID id;

      ...


      @OneToMany(mappedBy = "productEntity", cascade = CascadeType.ALL)
      private List<ProductAddonEntity> productAddonEntities;
 }


@Entity
@Table(name="product_addon")
public class ProductAddonEntity {
      @Id
      @GeneratedValue(generator = "uuid2")
      @GenericGenerator(name = "uuid2", strategy = "uuid2")
      private UUID id;

      ...


      @ManyToOne()
      @JoinColumn(name = "addon_id")
      private ProductEntity addonEntity;
 }

我要删除产品,并且该删除操作还应该删除与此产品相关的所有ProductAddon实体。因此,我声明了所有级联类型的一对多关系。 但是,当我尝试删除某些产品时,Hibernate最初尝试在product_addon表中设置null addon_id。但是此列具有非null约束,因此删除失败。

所以我添加了注释@ManyToOne参数

    @JoinColumn(name = "addon_id", nullable = false, updatable = false)

但是现在,休眠状态只是尝试删除产品,然后再删除与此产品连接的product_addon实体。并且此删除由于外键约束而失败(无法删除或更新父行:外键约束失败)。

这里可能有什么问题?此应用程序还使用liquibase,因此外来键不是由休眠生成的。例如,addon_id的外键没有删除操作,但是我认为休眠不需要这些操作,因为它适用于更高的数据层

1 个答案:

答案 0 :(得分:0)

孤立删除是一种主动删除级联模式,可在需要删除父对象(@OneToOne和@OneToMany关系)时删除子对象。 此功能是从JPA 2.0版本添加的。JPA deletion operation

两个设置之间的区别在于对断开关系的响应。例如,例如当将地址字段设置为null或另一个地址对象时。

@Entity   
class Employee {

@OneToOne(cascade=CascadeType.REMOVE)
private Address address;

}

如果仅指定了cascade = CascadeType.REMOVE,则不会执行自动操作,因为断开关系不是删除操作。

@Entity
class Employee {

@OneToOne(orphanRemoval=true)
private Address address;

}

如果指定了orphanRemoval = true,则会自动删除断开连接的Address实例。这对于清理没有所有者对象(例如Employee)的引用不应该存在的依赖对象(例如地址)很有用。