Hibernate @ManyToOne 删除一侧的条目,在多侧将 FK 设置为 NULL

发布于 2024-11-18 11:56:25 字数 1516 浏览 5 评论 0原文

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

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

我发现对反转的很好的解释 并发现 Author 是所有者,并且根据 此线程 当我删除子项(部门)时,FK 应设置为NULL。但这种情况不会发生,因为只有 Department 被删除,而 FK 保留在 Author 表中(这会导致 org.hibernate.ObjectNotFoundException:不存在具有给定标识符的行)。

当我将 CascadeType.REMOVE 添加到 Department 实体中的 @OneToMany 注释时,与 Department 相关的所有作者也将被删除。上述两种状态都是不可取的。我只想删除 Department 并将 Author 表中的 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;
}

提前致谢

I'm trying to learn to work with Hibernate but probably i don't understand @ManyToOne and inverse relations. I have two entities Author and Department. One Author has one Department, One Department has Many Authors.

When I remove Author, nothing should happen with Department. When I remove Department, FK in Author's table should be updated to NULL value (Author should NOT be removed).

I've found nice explanation of inversion and figured out that Author is an owning side and according to this thread when I remove child (Department) the FK should be set to NULL. But it doesn't happen because only Department is removed and FK remains in Author table (which leads to org.hibernate.ObjectNotFoundException: No row with the given identifier exists).

When I add CascadeType.REMOVE to @OneToMany annotation in Department entity then all Authors tied to Department are also removed. Neither of aforementioned states are desirable. I just want to remove Department and set FK in Author table to NULL. How to do that?

Author and Department entities with annotations:

@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;
}

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤独岁月 2024-11-25 11:56:25

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

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

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

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

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

There is no automatic way of setting all the foreign keys to null when some entity is removed. You have to explicitely get all the authors of the department, set their departement to null, and then remove the department.

You could also use a bulk update query to do this:

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

(and thus have just one query instead of n + 1), but be aware that the version field won't be updated, that there won't be any optimistic locking check, and that the already loaded departments of the session won't be affected (in memory) if you do so.

Note that you shouldn't have an ObjectNotFoundException when you're deleting an entity referenced by another one. Instead, you should enable a foreign key constraint in the database so that the removal of the department fails if there is still an author referencing it. That way, your data stays in a coherent state.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文