我有两个双向 OneToMany 关系的实体。例如
Employee.java
package com.jpademo.entities;
import java.io.Serializable;
import javax.persistence.*;
/**
* Entity implementation class for Entity: Employee
*
*/
@Entity
@Table(name = "Employee")
@SequenceGenerator(name = "Emp_Id_Gen", sequenceName = "EMP_ID_SEQ_GEN", allocationSize = 1)
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(generator = "Emp_Id_Gen")
private Integer employeeId;
private String Name;
@ManyToOne(cascade = { CascadeType.ALL })
private Department department;
public Integer getEmployeeId() {
return employeeId;
}
public void setEmployeeId(Integer employeeId) {
this.employeeId = employeeId;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
}
Department.java
package com.jpademo.entities;
import java.io.Serializable;
import java.util.List;
import javax.persistence.*;
/**
* Entity implementation class for Entity: Department
*
*/
@Entity
@Table(name = "Department")
@SequenceGenerator(name = "Dept_Id_Gen", sequenceName = "DEPT_ID_SEQ_GEN", allocationSize = 1)
public class Department implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(generator = "Dept_Id_Gen")
private Integer deptId;
private String deptName;
@OneToMany(mappedBy = "department", cascade = { CascadeType.MERGE,
CascadeType.PERSIST })
private List<Employee> employees;
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
}
EmployeeDAO.java
package com.jpademo.dao;
import java.util.Arrays;
import java.util.List;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import com.jpademo.entities.Department;
import com.jpademo.entities.Employee;
@Stateless(name = "employeeDAO")
@LocalBean
public class EmployeeDAO {
@PersistenceContext(unitName = "JPA2Pratice")
private EntityManager em;
public void saveEmployee() {
Employee emp = new Employee();
emp.setName("Mukesh Saini");
Department dept = new Department();
dept.setDeptName("Physics");
emp.setDepartment(dept);
em.persist(emp);
}
public void addEmployeeToDepartment() {
TypedQuery<Department> departmentQuery = em
.createQuery(
"SELECT dept FROM Department dept WHERE dept.deptId = :departmentId",
Department.class);
departmentQuery.setParameter("departmentId", 1);
Department dept = departmentQuery.getSingleResult();
// Employee already in department
List<Employee> currentEmpinDept = dept.getEmployees();
// Employee that need to be add in department
TypedQuery<Employee> employeeQuery = em.createQuery(
"SELECT emp FROM Employee emp WHERE emp.employeeId IN :empIds",
Employee.class);
employeeQuery.setParameter("empIds", Arrays.asList(2, 3));
List<Employee> employees = employeeQuery.getResultList();
currentEmpinDept.addAll(employees);
dept.setEmployees(currentEmpinDept);
em.merge(dept); // this does not update employee department
}
}
的persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="JPA2Pratice">
<jta-data-source>jdbc/MySQLDataSource</jta-data-source>
<properties>
<property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.logging.level.sql" value="FINE" />
<property name="eclipselink.logging.parameters" value="true" />
</properties>
</persistence-unit>
</persistence>
在EmployeeDAO em.merge(dept)中的方法 addEmployeeToDepartment 没有更新员工部门,我在这里做错了什么。或者 cascade是否仅在Parent之间工作?
感谢。
答案 0 :(得分:0)
我认为你不必担心合并,你只需要更新关系的两面。从您的查询返回的员工对象已经被管理/附加。
但根据here和here,仅仅在父部门对象上设置新的Employee对象列表是不够的。您还必须更新每个子Employee上对Department的引用。
所以你可以添加:
// ...
List<Employee> employees = employeeQuery.getResultList();
// NEW: Update owning side
for (Employee e : employees) {
e.setDepartment(dept);
}
currentEmpinDept.addAll(employees);
dept.setEmployees(currentEmpinDept);
//em.merge(dept); - DON'T THINK THIS IS NEEDED
}