java - 将新持久化的实体添加到关系的另一方持有的实体列表中,以维护双向关系

标签 java hibernate jpa hibernate-mapping bidirectional-relation

给定两个实体 DepartmentEmployeeDepartment 形成一对多关系至 Employee .

由于关系非常直观,我省略了实体类。

下面这段代码,简单的持久化了一个实体Employee .

public void insert() {
    Employee employee = new Employee();
    employee.setEmployeeName("k");

    Department department = entityManager.find(Department.class, 1L);
    employee.setDepartment(department);
    entityManager.persist(employee);
    entityManager.flush();

    List<Employee> employeeList = department.getEmployeeList();
    employeeList.add(employee);
}

下面的方法返回与特定部门关联的员工列表。

public List<Employee> getList() {
    return entityManager.find(Department.class, 1L).getEmployeeList();
}

这两种方法都是使用 CMT(这里不是 BMT)在无状态 EJB 中编写的,假设我们命名为 EmployeeService .

客户端应用程序像这样依次调用这些方法,

employeeService.insert();
List<Employee> employeeList = employeeService.getList();

for (Employee e : employeeList) {
    System.out.println(e.getEmployeeId() + " : " + e.getEmployeeName());
}

sout foreach 中的声明上面的循环显示新添加的 Employee实体到List<Employee>Departmentnull employeeId在其中 鉴于行 entityManager.flush();不存在于第一个代码片段中


EntityManager#persist(Object entity)不保证生成一个 id。 id 只保证在刷新时生成。

会发生什么,如果 entityManager.flush();被删除/评论,然后实体 Employee被添加到 Employee 的列表中s ( List<Employee> employeeList ) 与 null其中的标识符(基础数据库表中的主键列)。

维护双向关系的通常方法是什么?是EntityManager#flush();每次将实体添加到由关系的反面维护的实体集合时,总是需要生成与新持久化实体关联的 ID?

此外,是否总是需要手动删除 Employee来自 List<Employee> (由关系的反面维护 - Department )同时删除 Employee实体(使用 entityManager.remove(employee); )?


编辑:实体类:

部门:

@Entity
@Table(catalog = "testdb", schema = "", uniqueConstraints = {
@UniqueConstraint(columnNames = {"department_id"})})
public class Department implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "department_id", nullable = false)
    private Long departmentId;

    @Column(name = "department_name", length = 255)
    private String departmentName;

    @Column(length = 255)
    private String location;
    @OneToMany(mappedBy = "department", fetch = FetchType.LAZY)
    private List<Employee> employeeList = new ArrayList<Employee>(0);

    private static final long serialVersionUID = 1L;
    // Constructors + getters + setters + hashcode() + equals() + toString().
}

员工:

@Entity
@Table(catalog = "testdb", schema = "", uniqueConstraints = {
    @UniqueConstraint(columnNames = {"employee_id"})})
public class Employee implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "employee_id", nullable = false)
    private Long employeeId;

    @Column(name = "employee_name", length = 255)
    private String employeeName;
    @JoinColumn(name = "department_id", referencedColumnName = "department_id")
    @ManyToOne(fetch = FetchType.LAZY)
    private Department department;

    private static final long serialVersionUID = 1L;

    // Constructors + getters + setters + hashcode() + equals() + toString().
}

最佳答案

持久化Employee时,需要设置both sides of the association .

在你的部门你应该有这个方法:

public void addEmployee(Employee employee) {
    employees.add(employee);
    employee.setDepartment(this);
}

确保你cascade de PERSIST and MERGE events致您的 child 协会:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "department", orphanRemoval = true)
private List<Employee> children = new ArrayList<>();

持久化逻辑变为:

Employee employee = new Employee();
employee.setEmployeeName("k");

Department department = entityManager.find(Department.class, 1L);
department.addEmployee(employee);

关于java - 将新持久化的实体添加到关系的另一方持有的实体列表中,以维护双向关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30631326/

相关文章:

java - for 循环外部变量的动态添加和使用 - Selenium

java - 使用哪一个 : Java Swing or GTK+ for GNOME desktop application?

java - 使用 JPA 和 Hibernate 时如何选择 id 生成策略

hibernate 一对一: AnnotationException Referenced property not a (One|Many)ToOne

java - 使用 Hibernate 时 @Immutable 和 @Entity(mutable=false) 有什么区别

java - 正则表达式来获取一切

java - 选择性捕获可关闭资源

java - 找不到 hibernate 的 cfg.xml

java - 如何通过多重连接生成一些 JPA 实体?

java - SessionFactory.getCurrentSession() 与 EntityManager.createEntityManager()