JPA 中的级联类型
Cascade types in JPA
给定两个实体 Department
和 Employee
形成从 Department
到 Employee
的一对多关系。
由于关系非常直观,我省略了实体 类。
在Department
中:
@OneToMany(mappedBy = "department", fetch = FetchType.LAZY)
private List<Employee> employeeList = new ArrayList<Employee>(0);
在Employee
中:
@ManyToOne(fetch = FetchType.LAZY)
private Department department;
请注意我没有提到cascade = {CascadeType.MERGE}
虽然下面的关系在双方(拥有和反面)合并。
Employee employee = entityManager.find(Employee.class, 18L);
employee.setEmployeeName("zz");
Department department = employee.getDepartment();
employee.setDepartment(department);
department.setDepartmentName("e");
department.setLocation("e");
entityManager.merge(employee);
合并Employee
的同时,Department
也合并了
反之,在下面这个例子中,
Department department = entityManager.find(Department.class, 1L);
List<Employee> employeeList = department.getEmployeeList();
for(Employee e:employeeList) {
if(e.getEmployeeId().equals(27L)) {
e.setEmployeeName("xxx");
}
}
// No further EntityManager operation(s) here.
设置为 Employee
实例的新值直接合并到关联的基础数据库中。
来自 OpenJPA :
CascadeType.MERGE
: When merging entity state, also merge the entities
held in this field.
来自 EclipseLink Wiki :
MERGE – If the owning entity is merged, the merge is cascaded to the
target of the association.
来自 JPA Wiki Book:
MERGE
- Cascaded the EntityManager.merge()
operation. If merge()
is called on the parent, then the child will also be merged. This
should normally be used for dependent relationships. Note that this
only affects the cascading of the merge, the relationship reference
itself will always be merged. This can be a major issue if you use
transient variables to limit serialization, you may need to manually
merge, or reset transient
relationships in this case. Some JPA
providers provide additional merge operations.
关于上面的测试用例,我不准确地理解什么时候需要或有用cascade = {CascadeType.MERGE}
。在这种情况下 cascade = {CascadeType.MERGE}
有什么用?
那些测试用例如何在不使用 cascade = {CascadeType.MERGE}
的情况下分别合并 Department
和 Employee
?
我目前使用的是 EclipseLink 2.6.0。
您缺少的是 JPA 的一个基本功能:对托管实体所做的每个更改都会自动保存到数据库中。无需调用 merge()
或其他任何东西。您打开一个事务,获取实体并修改它们,然后提交事务,这就是您需要修改数据库的全部内容。
merge()
用于将更改从 分离的 实体复制到其 托管的 对应实体。
给定两个实体 Department
和 Employee
形成从 Department
到 Employee
的一对多关系。
由于关系非常直观,我省略了实体 类。
在Department
中:
@OneToMany(mappedBy = "department", fetch = FetchType.LAZY)
private List<Employee> employeeList = new ArrayList<Employee>(0);
在Employee
中:
@ManyToOne(fetch = FetchType.LAZY)
private Department department;
请注意我没有提到cascade = {CascadeType.MERGE}
虽然下面的关系在双方(拥有和反面)合并。
Employee employee = entityManager.find(Employee.class, 18L);
employee.setEmployeeName("zz");
Department department = employee.getDepartment();
employee.setDepartment(department);
department.setDepartmentName("e");
department.setLocation("e");
entityManager.merge(employee);
合并Employee
的同时,Department
也合并了
反之,在下面这个例子中,
Department department = entityManager.find(Department.class, 1L);
List<Employee> employeeList = department.getEmployeeList();
for(Employee e:employeeList) {
if(e.getEmployeeId().equals(27L)) {
e.setEmployeeName("xxx");
}
}
// No further EntityManager operation(s) here.
设置为 Employee
实例的新值直接合并到关联的基础数据库中。
来自 OpenJPA :
CascadeType.MERGE
: When merging entity state, also merge the entities held in this field.
来自 EclipseLink Wiki :
MERGE – If the owning entity is merged, the merge is cascaded to the target of the association.
来自 JPA Wiki Book:
MERGE
- Cascaded theEntityManager.merge()
operation. Ifmerge()
is called on the parent, then the child will also be merged. This should normally be used for dependent relationships. Note that this only affects the cascading of the merge, the relationship reference itself will always be merged. This can be a major issue if you use transient variables to limit serialization, you may need to manually merge, or resettransient
relationships in this case. Some JPA providers provide additional merge operations.
关于上面的测试用例,我不准确地理解什么时候需要或有用cascade = {CascadeType.MERGE}
。在这种情况下 cascade = {CascadeType.MERGE}
有什么用?
那些测试用例如何在不使用 cascade = {CascadeType.MERGE}
的情况下分别合并 Department
和 Employee
?
我目前使用的是 EclipseLink 2.6.0。
您缺少的是 JPA 的一个基本功能:对托管实体所做的每个更改都会自动保存到数据库中。无需调用 merge()
或其他任何东西。您打开一个事务,获取实体并修改它们,然后提交事务,这就是您需要修改数据库的全部内容。
merge()
用于将更改从 分离的 实体复制到其 托管的 对应实体。