jpa将同一对象与两个所有者持久化



如何在数据库中为包含相同对象的两个实体存储相同的表行?下面说明了我的无效尝试。

@Entity
public class Employee 
  {
  @ManyToOne(cascade=CascadeType.ALL)
  private Department department;
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private long id;
  private String name;
  ...
  <Getters and setters for all members here>
  ...
  }
@Entity
public class Department 
  {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private long id;
  private String name;
  @OneToMany(mappedBy="department")
  private Collection<Employee> employees;
  ...
  <Getters and setters for all members here>
  ...
  }

在Servlet中,我尝试以下操作:

Department department=new Department();
department.setName("HR");
Employee employee1=new Employee();
employee1.setName("Bob");
employee1.setDepartment(department);
Employee employee2=new Employee();
employee2.setName("Anna");
employee2.setDepartment(department);
...
em.persist(employee1);
em.persist(employee2);

当我这样做时,当employee2被持久化时,我得到一个错误,即department的主键已经在数据库中,因为它试图第二次添加同一个部门。

如何使两名员工都指向数据库中的同一行。

为了实现这一点,我是否必须从反面工作,将员工添加到部门中?

我觉得我错过了一些基本的东西。

如果是外键,我认为您需要在部门id为的Employee类中添加联接列关系(与@JoinColumn)。有关详细信息,请参阅此链接。

在测试了一些示例后,我确定了至少两种方法来实现这一点。

第一种方法似乎是最简单的,不使用级联(从关系中删除cascade=CascadeType.ALL),而是先插入部门。

Department department=new Department();
department.setName("HR");
Employee employee1=new Employee();
employee1.setName("Bob");
Employee employee2=new Employee();
employee2.setName("Anna");
...
em.persist(department);
employee1.setDepartment(department);
em.persist(employee1);
employee2.setDepartment(department);
em.persist(employee2);

这是因为Employee中的ManyToOne关系将外键存储到Department表中。必须先保留部门,否则在添加员工时外键将不存在。

实现这一点的另一种方法是将级联放在相反的一侧。

在部门类别更改

@OneToMany(mappedby="department")

@OneToMany(mappedby="department",cascade=CascadeType.ALL)

然后以下操作将起作用:

Department department=new Department();
department.setName("HR");
Employee employee1=new Employee();
employee1.setName("Bob");
employee1.setDepartment(department);
Employee employee2=new Employee();
employee2.setName("Anna");
employee2.setDepartment(department);
...
department.addEmployee(employee1);
department.addEmployee(employee2);
em.persist(department);

这两者都将在数据库中产生两个表

department
ID  NAME
3    HR
employee
ID  NAME DEPARTMENT_ID
20   Bob     3
21   Anna    3

注意:准确的身份证号码可能会有所不同,因为它们是在这里自动生成的。

另一种方法是让部门成为所有者,让员工成为相反的关系,并执行类似的操作。

最新更新