Hibernate @ManyToOne 删除一侧的条目,在多侧将 FK 设置为 NULL
我正在尝试学习使用 Hibernate,但可能我不理解 @ManyToOne
和逆关系。我有两个实体作者
和部门
。一位作者有一个部门,一个部门有许多作者。
当我删除作者时,部门不会发生任何事情。当我删除部门时,作者表中的 FK 应更新为 NULL 值(不应删除作者)。
我发现对反转的很好的解释 并发现 Author
是所有者,并且根据 此线程 当我删除子项(部门)时,FK 应设置为NULL
。但这种情况不会发生,因为只有 Department 被删除,而 FK 保留在 Author 表中(这会导致 org.hibernate.ObjectNotFoundException:不存在具有给定标识符的行)。
当我将 CascadeType.REMOVE
添加到 Department
实体中的 @OneToMany
注释时,与 Department 相关的所有作者也将被删除。上述两种状态都是不可取的。我只想删除 Department 并将 Author 表中的 FK 设置为 NULL。怎么做呢?
带注释的 Author
和 Department
实体:
@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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当删除某些实体时,没有自动将所有外键设置为
null
的方法。您必须明确获取该部门的所有作者,将其部门设置为 null,然后删除该部门。您还可以使用批量更新查询来执行此操作:(
因此只有一个查询而不是 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:
(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.