我遗漏了一些非常基本的东西。鉴于以下两个实体Department
(反面)和Employee
(拥有面)形成了从Department
到Employee
的一对多关系。
Department.java
@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().
// No defensive link (relationship) management methods have yet been added to.
// CascadeType is also kept at a distance for now.
}
Employee.java
@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().
// No defensive link (relationship) management methods have yet been added to.
// CascadeType is also kept at a distance for now.
}
下面给出了无状态EJB(使用CMT)中的一些方法,分别进行持久化,合并和删除操作。
public List<Employee> persist() {
Employee employee = new Employee();
employee.setEmployeeName("a");
employee.setDepartment(entityManager.getReference(Department.class, 1L));
entityManager.persist(employee);
return employee.getDepartment().getEmployeeList();
}
public List<Employee> merge(Employee employee) {
employee.setEmployeeName("b");
employee.setDepartment(entityManager.getReference(Department.class, 1L));
return entityManager.merge(employee).getDepartment().getEmployeeList();
}
public List<Employee> remove(Employee employee) {
entityManager.remove(entityManager.contains(employee) ? employee : entityManager.merge(employee));
return entityManager.getReference(Employee.class, employee.getEmployeeId()).getDepartment().getEmployeeList();
}
public Employee getEmployeeById(Long id) {
return entityManager.find(Employee.class, id);
}
这些方法由关联的应用程序客户端在非事务环境中依次(逐个)调用。
List<Employee> persistedList = employeeSessionBean.persist();
for (Employee employee : persistedList) {
System.out.println(employee.getEmployeeId() + " : " + employee.getEmployeeName());
}
List<Employee> mergedList = employeeSessionBean.merge(employeeSessionBean.getEmployeeById(23L));
for (Employee employee : mergedList) {
System.out.println(employee.getEmployeeId() + " : " + employee.getEmployeeName());
}
List<Employee> listAfterRemoving = employeeSessionBean.remove(employeeSessionBean.getEmployeeById(23L));
for (Employee employee : listAfterRemoving) {
System.out.println(employee.getEmployeeId() + " : " + employee.getEmployeeName());
}
关系反面的列表(List<Employee>
)会自动反映上述每个操作中的正确状态。
Employee
实体持久存在时,列表中会列出该实体
反面(我没有明确添加新的持久化
Employee
实体到反面的List<Employee>
。Employee
实体时,对实体所做的更改会自动反映在List<Employee>
的相反实体上(我没有明确更改列表所持有的相应实体)员工(List<Employee>
)的反面)。Employee
实体时,也会将其删除
从关系的反面列表(我不是
明确地从反面的列表中删除该实体。)我目前使用的是EcliseLink 2.6.0。为什么我看到这样的行为似乎与以下文本不匹配?
与所有双向关系一样,它是您的对象模型& 应用程序负责维护两者之间的关系 方向。如果你在一边添加或删除,JPA中没有魔法 对于集合,您还必须在另一侧添加或删除, 见object corruption。从技术上讲,数据库将会更新 正确的,如果你只是从拥有方添加/删除 关系,但那么你的对象模型将不同步,这 会导致问题。
http://en.wikibooks.org/wiki/Java_Persistence/ManyToMany#Bi-directional_Many_to_Many
答案 0 :(得分:3)
这意味着,根据您的特定示例,如果您更改代码以将员工添加到部门(而不是设置部门的其他方式),那么您会注意到这不会自动设置部门雇员。您必须编写代码才能显式执行此操作。
因此,即使您显示的特定代码路径确实有效,但这并不意味着您可以依赖它。我可以猜测为什么这样做 - 该集合被延迟加载,并且由于该对象在加载集合之前被持久化,因此它能够从数据库中提取正确的数据。
最好的解决方案是注意文档中的建议,并在双向关系的两端正确设置状态,尽管有性能方面的考虑(这可以在以后进行微调)。