如果在合并时其父项的引用在实体中设置为 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)
private List<Employee> employeeList = new ArrayList<Employee>(0);
拥有方(员工):
@JoinColumn(name = "department_id", referencedColumnName = "department_id")
@ManyToOne(fetch = FetchType.LAZY)
private Department department;
合并客户端提供的 Employee
实体的方法,其中包含一个空 Department
:
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);
}
}
所提供的 Employee
是一个分离的实体。假设 Department
对于 Employee
是可选的,因此存在一个空外键 (ON DELETE SET NULL
).
当在合并提供的 Employee
实体之前,提供的 Employee
不包含 Department
(因为它在编辑 Employee
实体时已被客户端设置为空)?
我认为,提供者会保留关系另一端员工列表中的 Employee
引用,否则将悬空。
员工没有部门通常是不切实际的,但这只是一个例子。不用说其他类型的关联中也存在空外键。
我看JPA 2.1 Specification的Chapter 2.9 Entity Relationships是没必要,因为你指定了orphanRemoval
。以下是规范的话:
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).
反面(部门):
@OneToMany(mappedBy = "department", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Employee> employeeList = new ArrayList<Employee>(0);
拥有方(员工):
@JoinColumn(name = "department_id", referencedColumnName = "department_id")
@ManyToOne(fetch = FetchType.LAZY)
private Department department;
合并客户端提供的 Employee
实体的方法,其中包含一个空 Department
:
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);
}
}
所提供的 Employee
是一个分离的实体。假设 Department
对于 Employee
是可选的,因此存在一个空外键 (ON DELETE SET NULL
).
当在合并提供的 Employee
实体之前,提供的 Employee
不包含 Department
(因为它在编辑 Employee
实体时已被客户端设置为空)?
我认为,提供者会保留关系另一端员工列表中的 Employee
引用,否则将悬空。
员工没有部门通常是不切实际的,但这只是一个例子。不用说其他类型的关联中也存在空外键。
我看JPA 2.1 Specification的Chapter 2.9 Entity Relationships是没必要,因为你指定了orphanRemoval
。以下是规范的话:
Associations that are specified as
OneToOne
orOneToMany
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 oforphanRemoval
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).