如果在合并时在实体中将父实体的引用设置为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?

查看:122
本文介绍了如果在合并时在实体中将父实体的引用设置为null,是否有必要从实体的反面删除实体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

反面(部门):

  @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 Employees 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆