禁用外键取消引用休眠

时间:2019-02-06 08:28:56

标签: database hibernate spring-data-jpa spring-data

在某些情况下,Hibernate在删除时会取消引用外键

在Hibernate中定义OneToMany关系时(使用批注)。在映射方面(很多方面),我使用id列而不是实体来定义此类映射。这主要是因为在“一个”方面存在此类实体的列表。这样定义属性有助于避免循环依赖。

在下面的示例中,Listing实体通过mainListingId列保存对MainListing的引用。而MainListing实体包含一个Listing实体的集合。

在删除实体时,我在数据库级别应用软删除。每个表都有一个删除列(布尔),以指示是否删除了一行。因此,不需要完全删除删除数据库中的条目。

我遇到的问题与休眠中的删除过程有关。上面定义的设置可以与其他实体关系设置很好地配合使用。但是,在上面定义的用例中,执行删除操作时,会执行设置fk_id=null的更新语句,从而导致条目被取消引用。在此示例中,发生以下情况mainListingId=null,从而断开了列表和MainListing之间的链接。这不是预期的行为,因为删除后我仍然希望能够检索MainListing实体及其所有关联的清单。

注意:仅在以下情况下会发生这种情况 -@OneToMany关系 -ID列引用而不是实体(下面的代码段)

@Entity
@SQLDelete(sql = "update main_listing set deleted=1 where id=?")
MainListing { 
    ...
    @OneToMany(cascade = [CascadeType.ALL], fetch = FetchType.EAGER)
    @JoinColumn(name = "main_listing_id", referencedColumnName = "id")
    @Where(clause = "deleted=false")
    var listings: List<Listing> = emptyList(),
    ...
}

@Entity
@SQLDelete(sql = "update listing set deleted=1 where id=?")
Listing {
    ...
    @Column(name = "main_listing_id", updatable = false)
    var mainListingId: Long? = null,
    ...
}

1 个答案:

答案 0 :(得分:0)

解决方案是将以下内容添加到父实体

@JoinColumn(... nullable=false, insertable=false)

以上内容用于以下目的

  • 解决了删除时的取消引用问题
  • 由于默认情况下updatabale = true,因此不影响更新行为
  • 不影响插入,因为插入时外键的默认值为null