Hibernate @ManyToOne删除一侧的条目,在多方将FK设置为NULL [英] Hibernate @ManyToOne remove entry at One side, set FK to NULL at Many side
问题描述
我正在尝试学习使用Hibernate,但可能我不理解 @ManyToOne
和反向关系。我有两个实体作者
和部门
。一个作者有一个部门,一个部门有很多作者。
当我删除作者时,部门不会发生任何事情。当我删除部门时,作者表中的FK应更新为 NULL
值(不应删除作者)。
我发现对反演有很好的解释并且发现作者
是一个拥有者并且根据此主题当我删除子(Department)时,FK应设置为 NULL
。但它不会发生,因为只有Department被删除而FK仍然在Author表中(这导致 org.hibernate.ObjectNotFoundException:没有给定标识符的行存在
)。 / p>
当我将 CascadeType.REMOVE
添加到 @OneToMany
注释时在部门
实体中,所有与部门相关的作者也将被删除。上述两种状态都不可取。我只想删除Department并将Author表中的FK设置为 NULL
。怎么做?
作者
和部门
实体带注释:
@Entity
@Table(name =author)
公共类作者实现Serializable {
@Id
@Column(name =idauthor)
@GeneratedValue
private Integer idAuthor;
@DepartmentFormat
@ManyToOne
@JoinColumn(name =department,nullable = true)
私人部门部门;
}
@Entity
@Table(name =department)
公共类部门实现Serializable {
@Id
@Column(name =iddepartment)
@GeneratedValue
private Integer iddepartment;
@OneToMany(mappedBy =department,cascade = {CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH})
private Set< Author>作者;
}
提前致谢
当删除某个实体时,没有自动方法将所有外键设置为 null
。您必须明确地获取部门的所有作者,将他们的部分设置为null,然后删除部门。
您还可以使用批量更新查询来执行此操作:
更新作者a set a.department = null其中a.department =:department
(因此只有一个查询而不是n + 1),但要注意版本字段不会更新,不是任何乐观的锁定检查,并且如果你这样做,会话的已经加载的部门将不会受到影响(在内存中)。
注意你不应该当您删除另一个实体引用的实体时,不会有ObjectNotFoundException。相反,您应该在数据库中启用外键约束,以便在仍有作者引用它时删除部门失败。这样,您的数据就会保持一致状态。
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
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.
这篇关于Hibernate @ManyToOne删除一侧的条目,在多方将FK设置为NULL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!