1

私は非常に基本的なものを欠いています。以下の 2 つのエンティティDepartment(逆側) とEmployee(所有側) が から までの 1 対多の関係を形成し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.
}

従業員.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);
}

これらのメソッドは、非トランザクション環境で、関連付けられたアプリケーション クライアントによって順番に (1 つずつ) 呼び出されます。

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に明示的に追加するわけではありません )。EmployeeList<Employee>
  • エンティティがマージされると、Employeeエンティティに加えられた変更は、反対側の対応するエンティティに自動的に反映されますList<Employee>(反対側の従業員のリスト ( ) が保持する対応するエンティティを明示的に変更するわけではありませんList<Employee>)。
  • 同様に、Employeeエンティティが削除されると、関係の逆側のリストからも削除されます (逆側のリストからそのエンティティを明示的に削除しているわけではありません)。

現在、EcliseLink 2.6.0 を使用しています。次のテキストと一致しないような動作が見られるのはなぜですか?

すべての双方向の関係と同様に、双方向の関係を維持するのはオブジェクト モデルとアプリケーションの責任です。JPA には魔法はありません。コレクションの片側に追加または削除する場合は、反対側にも追加または削除する必要があります。オブジェクトの破損を参照してください。技術的には、リレーションシップの所有側のみを追加/削除すると、データベースは正しく更新されますが、オブジェクト モデルが同期されなくなり、問題が発生する可能性があります。

http://en.wikibooks.org/wiki/Java_Persistence/ManyToMany#Bi-directional_Many_to_Many

4

1 に答える 1