这是一种很常见的做法/情况/要求,其中父母的子女可以迁移到另一父母。如果orphanRemoval
设置为true
这种关系的反面会发生什么?
作为示例,考虑以下任何简单的一对多关系。
反面(系):
@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, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
private Department department;
合并以下操作/动作(department
客户端提供的分离实体)时,
Employee employee = entityManager.find(Employee.class, 1L);
Department newDepartment = entityManager.contains(department) ? department : entityManager.merge(department);
if (!newDepartment.equals(employee.getDepartment())) {
employee.getDepartment().getEmployeeList().remove(employee);
// Since orphanRemoval is set to true,
// this should cause a row from the database table to be removed inadvertently
// by issuing an addition DELETE DML statement.
}
employee.setDepartment(newDepartment);
employee.setEmployeeName("xyz");
List<Employee> employeeList = newDepartment.getEmployeeList();
if (!employeeList.contains(employee)) {
employeeList.add(employee);
}
entityManager.merge(employee);
当然,使用关联实体中的防御性链接(关系)管理方法可以更好地完成/处理添加和删除员工的操作。
客户提供部门实例。它是一个独立的实体。它可以是相同的部门,也可以是不同的部门,具体取决于相关客户执行的管理操作。因此,如果客户提供的部门实例与当前部门所拥有的部门实例不同Employee
,则应首先从employeeList
当前
旧 部门所拥有的雇员列表中与之相反的一方将其删除,然后Employee
再添加将其添加到新department
供应商所拥有的员工列表中。
可以猜测,在Employee
从Employee
雇员部门-
旧部门当前所引用的雇员列表中删除实例时(在触发此操作之前),即在将孩子从其父项迁移到父项时,应无意中从数据库中删除该行。另一个父级,则需要先从其父级父级中删除该子级,然后再不经意地从数据库(orphanRemoval= true
)中删除该子行。
但是,数据库表中的雇员行与更新的列值保持不变。除一条语句外,UPDATE
不生成任何DML语句。
我是否可以考虑以这种方式将子代从其父代迁移到另一个父代,是否会无意间从数据库表中删除那些子代, 而不 应该 这样 做?
当前使用具有JPA 2.1的EclipseLink 2.6.0。
编辑:
如果Employee
仅从相反侧的列表中删除一个实体(因此,在删除该实体后不将其添加到列表中-
不会迁移到另一个父级,而只是删除了),则该对象对应的行也照常从数据库中删除(orphanRemoval = true
)但是,当Employee
实体(子级)从其本机父级列表中删除后,该实体(子级)被添加到另一个父级列表中时,该行只是被更新(实体的迁移)。
提供者似乎很聪明,可以检测到孩子从其父母到另一父母的迁移,作为更新。
在Hibernate(最终版4.3.6)和EclipseLink(2.6.0)上都可以看到相同的行为,但是如果它是提供程序特定的行为(不是可移植的),则不能依靠该行为。我在JPA规范中找不到有关此行为的任何信息。
JPA规范中对此进行了记录。
第 3.2.4 节(节选):
应用于实体X的刷新操作的语义如下:
- 如果X是受管实体,则将其同步到数据库。
- 对于由X的关系引用的所有实体Y,如果已使用级联元素值Cascade = PERSIST或Cascade =
ALL注释了与Y的关系,则对Y应用持久性操作
第 3.2.2 节(节选):
应用于实体X的persist操作的语义如下:
- 如果X是已删除的实体,则它将被管理。
orphanRemoval
JPA
javadoc:
(可选)是否 将删除操作 应用于已从关系中删除的实体,以及是否将删除操作应用于这些实体。
orphanRemoval
hibernate文档:
如果一个实体从删除
@OneToMany
集合或相关实体是由非关联@OneToOne
的关联,这种关联的实体可以 标记为删除
,如果orphanRemoval
设置为true
。
因此,您将雇员E
从部门中删除D1
,并将其添加到部门中D2
。
然后,Hibernate将部门D1
与数据库同步,发现该部门E
不在员工列表中,并标记E
为删除。然后,它D2
与数据库同步,并将PERSIST
操作级联到员工列表(第3.2.4节)。由于E
现在位于此列表中,因此级联将应用于此列表,并且Hibernate取消安排删除操作的时间表(第3.2.2节)。
您可能还想看看这个问题。
“如果orphanRemoval
设置为true
这种关系的反面会发生什么?”
您已经将它设置在反面(反面是声明的那一面mappedBy
)。如果你的意思是,如果它被设置在什么 其他
方面(@ManyToOne
在这种情况下),那就不是为什么没有在这样的属性意义和的@ManyToOne
和@ManyToMany
。
重要提示:如果你正在阅读这篇文章,那么也考虑看看这篇文章进行深入讨论。 这是一个非常常见的做法/情况/要求,其中一个父级的子级可以迁移到另一个父级。如果在这种关系的反面将设置为会发生什么? 考虑作为示例,任何简单的一对多关系如下。 反面(部门) : 拥有方(员工): 在合并如下操作/动作时(其中< code>department是由客户端提供的分离实体), 当然,添加和删除员工可能最好使用关联实体
VSCode很棒,但它需要稍微小心的设置。 有许多秘密提示要遵循,例如 vscode增加的另一个惊人的新特性: https://code.visualstudio.com/docs/editor/settings-sync
如何将数据从一个活动转移到另一个活动并将其设置为文本视图? 这就是我的意图: 我想将questions_score传递到另一个活动,并将其设置为文本视图。
问题内容: 我在这里有一个简单的设置: 我有一个父组件,该父组件有2个子组件。在第一个子组件中:用户更改输入的值。然后,该更改的值将是我想要从该孩子传递给父对象的道具,以便可以将其传递给与同一父组件相连的另一个孩子。 当前设置的这个,请查看 从用户输入到UI更改的流程:1.在“ Child 1”中:调整一个滑块,将onChange值传递给父组件;2.将此属性(新的滑块值)传递给Parent组件,以
我一直在设计一个基于Swing的桌面RPG程序,以促进带有GUI控制元素的基于文本的角色扮演。 为了促进这一点,每个正在运行的客户端都会获得一个带有所有重要JFrames的主桌面(托管客户端上的“GM Desktop”和远程客户端上的“Player Desktop”)。此外,GM和Players都可以为角色打开“透视桌面”,为他们提供一个单独的JDesktopPane,其中包含提供该角色视角的“角
在我们公司,我们有一个必须使用的Eclipse错误/警告设置的严格列表。使用此列表编译更改时,在签入之前不应存在任何错误/警告。 这些错误/警告可以在Eclipse的首选项下找到- 我是IntelliJ用户。IntelliJ有一个类似的概念,叫做“检查”。检查设置可以在设置下找到- 是否有人知道如何将Eclipse错误/警告迁移到最接近的IntelliJ检查设置上。我可以看到有一种方法可以导出/导