如何在数据库中为包含相同对象的两个实体存储相同的表行?下面说明了我的无效尝试。
@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
注意:准确的身份证号码可能会有所不同,因为它们是在这里自动生成的。
另一种方法是让部门成为所有者,让员工成为相反的关系,并执行类似的操作。