jpa与两个所有者持有相同的对象

时间:2016-03-24 05:24:19

标签: java database jpa duplicates inverse

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

@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被持久化时,部门的主键已经在数据库中,因为它试图再次添加相同的部门时,会出现错误。

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

我是否必须通过将员工添加到部门来实现这一目标?

我觉得我在这里缺少一些基本的东西。

2 个答案:

答案 0 :(得分:2)

我认为你需要在Employee类中添加连接列关系(使用@JoinColumn),如果它是外键,则使用部门ID。有关详细信息,请参阅此link

答案 1 :(得分:0)

通过测试一些例子,我确定了至少两种方法来实现这一目标。

第一种方式,似乎最简单,不是使用级联(从关系中删除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表中。必须首先坚持部门,否则在添加员工时,外键不会存在。

实现这一目标的另一种方法是将级联放在反面。

在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

注意:确切的ID号可能会有所不同,因为它们是在这里自动生成的。

另一种方法是让部门所有者和员工成反比关系并执行类似的事情。