【问题标题】:Hibernate @ManyToOne remove entry at One side, set FK to NULL at Many sideHibernate @ManyToOne 删除一侧的条目,在多侧将 FK 设置为 NULL
【发布时间】:2011-07-06 12:55:27
【问题描述】:

我正在尝试学习使用 Hibernate,但可能我不理解 @ManyToOne 和反向关系。我有两个实体AuthorDepartment。一个作者有一个部门,一个部门有许多作者。

当我删除作者时,部门不会发生任何事情。当我删除部门时,作者表中的 FK 应更新为 NULL 值(不应删除作者)。

我发现nice explanation of inversion 并发现Author 是拥有方,根据this thread,当我删除子(部门)时,FK 应设置为NULL。但它不会发生,因为只删除了 Department 并且 FK 保留在 Author 表中(导致 org.hibernate.ObjectNotFoundException: No row with the given identifier exists)。

当我在Department 实体中将CascadeType.REMOVE 添加到@OneToMany 注释时,所有与部门相关的作者也将被删除。上述两种状态都是不可取的。我只想删除部门并将作者表中的 FK 设置为NULL。该怎么做?

AuthorDepartment 带有注释的实体:

@Entity
@Table(name = "author")
public class Author implements Serializable {

    @Id
    @Column(name = "idauthor")
    @GeneratedValue
    private Integer idAuthor;

    @DepartmentFormat
    @ManyToOne
    @JoinColumn(name = "department", nullable = true)
    private Department department;
}

@Entity
@Table(name="department")
public class Department implements Serializable {

    @Id
    @Column(name="iddepartment")
    @GeneratedValue
    private Integer iddepartment;

    @OneToMany(mappedBy = "department", cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
    private Set<Author> authors;
}

提前致谢

【问题讨论】:

    标签: java hibernate spring null many-to-one


    【解决方案1】:

    当删除某些实体时,没有自动将所有外键设置为 null 的方法。您必须明确获取部门的所有作者,将他们的部门设置为 null,然后删除部门。

    您也可以使用批量更新查询来执行此操作:

    update Author a set a.department = null where a.department = :department
    

    (因此只有一个查询而不是 n + 1),但请注意版本字段不会被更新,不会有任何乐观锁定检查,并且会话的已加载部门如果您这样做,将不会受到影响(在内存中)。

    请注意,当您删除另一个实体引用的实体时,不应出现 ObjectNotFoundException。相反,您应该在数据库中启用外键约束,以便如果仍有作者引用该部门,则删除部门会失败。这样一来,您的数据就会保持一致。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-12
      • 2012-06-12
      • 1970-01-01
      • 2013-03-22
      • 1970-01-01
      • 2014-11-28
      • 2012-06-17
      相关资源
      最近更新 更多