如果在合并时在实体中将父实体的引用设置为null,是否有必要从实体的反面删除实体? [英] Is it necessary to remove an entity from the collection on the inverse side, if its parent's reference is set to null in the entity while merging?
问题描述
@OneToMany(mappedBy =department,fetch = FetchType.LAZY,cascade = CascadeType.ALL,orphanRemoval = true)
私人列表< Employee> employeeList = new ArrayList< Employee>(0);
拥有方(员工):
@JoinColumn(name =department_id,referencedColumnName =department_id)
@ManyToOne(fetch = FetchType.LAZY)
私人部门部门;
合并提供的 Employee
实体的方法由一个客户有一个空部门
在其中:
公共职员更新(员工员工){
部门部门= employee.getDepartment();
if(department == null){
Employee managedEmployee = entityManager.find(Employee.class,employee.getEmployeeId());
//获取可能仍然保留其部门的原始Employee实体。
if(managedEmployee == null){
throw new EntityNotFoundException();
}
部门managedDepartment = managedEmployee.getDepartment();如果(managedDepartment!= null){
managedEmployee.getDepartment()。getEmployeeList()。remove(managedEmployee);
//从反面删除一个Employee实体
//因为在Employee被合并后它不再指向Employee。
}
return entityManager.merge(employee);
code
$ b提供的 Employee code>是一个分离的实体。假设 Department 对于 Employee
s是可选的,因此存在空外键( ON DELETE SET NULL
)。
是否有必要显式移除 Employee
实体如关系反面( Department
)的员工列表中的 update()
方法所示,当提供的 Employee
不包含 Department
时(因为它在编辑时已被客户端设置为null Employee
实体)
我认为,供应商会保留,关系反面的员工名单中的员工
参考,否则就是悬挂。
没有部门的员工通常是不切实际的,但这仅仅是一个例子。不用说在其他类型的关联中存在空外键。
我读过Chapter 2.9 Entity Relationships的 JPA 2.1规范是因为你指定了 orphanRemoval
,所以没有必要。这里是规范的单词:
指定为 OneToOne
的关联或 OneToMany
支持使用orphanRemoval选项的
。当
orphanRemoval有效时,以下行为适用:
-
如果作为关系目标的实体是从关系中删除(通过将关系设置为null或从关系集合中删除
实体),删除操作将应用于被孤立实体的
。清除操作时,清除操作应用
。 orphanRemoval
功能是
,用于由其父母
实体私有拥有的实体。否则便携式应用程序必须不依赖
特定的删除顺序,并且不得重新分配具有
的实体与另一个关系孤立或以其他方式尝试坚持
it。如果孤立实体是分离的,新的或删除的
实体,则 orphanRemoval
的语义不适用。
-
如果将删除操作应用于托管源实体,则删除操作将按照
3.2.3节的规则级联到
中的关系目标,因此没有必要为关系指定 cascade = REMOVE
)。
Inverse side (Department) :
@OneToMany(mappedBy = "department", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Employee> employeeList = new ArrayList<Employee>(0);
Owning side (Employee) :
@JoinColumn(name = "department_id", referencedColumnName = "department_id")
@ManyToOne(fetch = FetchType.LAZY)
private Department department;
The method that merges an Employee
entity supplied by a client having a null Department
in it :
public Employee update(Employee employee) {
Department department = employee.getDepartment();
if (department == null) {
Employee managedEmployee = entityManager.find(Employee.class, employee.getEmployeeId());
// Obtain the original Employee entity which may still have its Department intact.
if (managedEmployee == null) {
throw new EntityNotFoundException();
}
Department managedDepartment = managedEmployee.getDepartment();
if (managedDepartment != null) {
managedEmployee.getDepartment().getEmployeeList().remove(managedEmployee);
// Removing an Employee entity from the list on the inverse side,
// since it will no longer be pointing to Employee after Employee is merged.
}
return entityManager.merge(employee);
}
}
The supplied Employee
is a detached entity. Suppose that Department
is optional for Employee
s and hence, there is a null foreign key (ON DELETE SET NULL
).
Is it necessary to explicitly remove an Employee
entity as shown in the update()
method above from the employee list on the inverse side of the relationship (Department
), when the supplied Employee
does not contain a Department
(because it has already been set to null by the client while editing the Employee
entity) before merging the supplied Employee
entity?
I think, the provider will keep, the Employee
reference in the list of employees on the inverse side of the relationship, on dangling otherwise.
It is generally impractical to have an employee without a department but this is just an example. Needless to mention that null foreign keys exist in other types of associations.
解决方案 My reading of Chapter 2.9 Entity Relationships of the JPA 2.1 Specification is that it is not necessary since you have specified orphanRemoval
. Here are the words of the spec:
Associations that are specified as OneToOne
or OneToMany
support use
of the orphanRemoval option. The following behaviors apply when
orphanRemoval is in effect:
If an entity that is the target of the relationship is removed from the relationship (by setting the relationship to null or removing the
entity from the relationship collection), the remove operation will be
applied to the entity being orphaned. The remove operation is applied
at the time of the flush operation. The orphanRemoval
functionality is
intended for entities that are privately "owned" by their parent
entity. Portable applications must otherwise not depend upon a
specific order of removal, and must not reassign an entity that has
been orphaned to another relationship or otherwise attempt to persist
it. If the entity being orphaned is a detached, new, or removed
entity, the semantics of orphanRemoval
do not apply.
If the remove operation is applied to a managed source entity, the remove operation will be cascaded to the relationship target in
accordance with the rules of section
3.2.3, (and hence it is not necessary to specify cascade=REMOVE
for the relationship).
这篇关于如果在合并时在实体中将父实体的引用设置为null,是否有必要从实体的反面删除实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!