Hibernate多対多注釈チュートリアル

1前書き

このクイックチュートリアルでは、Hibernateで @ ManyToMany アノテーションを使用してこのタイプの関係を指定する方法について簡単に説明します。

** 2典型的な例

単純なEntity Relationship Diagramから始めましょう - これは2つのエンティティ employee と__projectの間の多対多の関連を示しています

リンク:/uploads/New.png%20794w[]

このシナリオでは、任意の特定の employee を複数のプロジェクトに割り当てることができ、 project には複数の従業員が働いている可能性があり、この2つの間で多対多の関連付けが行われます。

employee id を主キーとする employee テーブルと、 project id を主キーとする project テーブルがあります。両側を接続するには、結合表 employee project__が必要です。

3データベース設定

spring hibernate many to__manyという名前のデータベースが既に作成されているとしましょう。

また、 employee id project id を外部キーとして持つ employee project 結合テーブルと共に employee テーブルと project__テーブルを作成する必要があります。

CREATE TABLE `employee` (
  `employee__id` int(11) NOT NULL AUTO__INCREMENT,
  `first__name` varchar(50) DEFAULT NULL,
  `last__name` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`employee__id`)
) ENGINE=InnoDB AUTO__INCREMENT=17 DEFAULT CHARSET=utf8;

CREATE TABLE `project` (
  `project__id` int(11) NOT NULL AUTO__INCREMENT,
  `title` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`project__id`)
) ENGINE=InnoDB AUTO__INCREMENT=18 DEFAULT CHARSET=utf8;

CREATE TABLE `employee__project` (
  `employee__id` int(11) NOT NULL,
  `project__id` int(11) NOT NULL,
  PRIMARY KEY (`employee__id`,`project__id`),
  KEY `project__id` (`project__id`),
  CONSTRAINT `employee__project__ibfk__1`
   FOREIGN KEY (`employee__id`) REFERENCES `employee` (`employee__id`),
  CONSTRAINT `employee__project__ibfk__2`
   FOREIGN KEY (`project__id`) REFERENCES `project` (`project__id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

データベースを設定したら、次のステップはMavenの依存関係とHibernateの設定の準備です。これに関する情報は Spring付きHibernate4のガイド

4モデルクラス

モデルクラス Employee および Project は、JPAアノテーションを使用して作成する必要があります。

@Entity
@Table(name = "Employee")
public class Employee {
   //...

    @ManyToMany(cascade = { CascadeType.ALL })
    @JoinTable(
        name = "Employee__Project",
        joinColumns = { @JoinColumn(name = "employee__id") },
        inverseJoinColumns = { @JoinColumn(name = "project__id") }
    )
    Set<Project> projects = new HashSet<>();

   //standard constructor/getters/setters
}
@Entity
@Table(name = "Project")
public class Project {
   //...

    @ManyToMany(mappedBy = "projects")
    private Set<Employee> employees = new HashSet<>();

   //standard constructors/getters/setters
}

ご覧のとおり、 Employee クラスと Project クラスの両方が互いに参照しています。つまり、それらの間の関連は双方向です。

多対多関連をマッピングするために、 @ ManyToMany @ JoinTable 、および @ JoinColumn アノテーションを使用します。それらを詳しく見てみましょう。

両方のクラスで @ ManyToMany アノテーションを使用して、エンティティ間の多対多の関係を作成します。

この例では、所有側は Employee なので、結合テーブルは Employee クラスの @ JoinTable アノテーションを使用して所有側で指定されます。 @ JoinTable は、結合/リンクテーブルを定義するために使用されます。この場合、それは Employee Project.__です。

@ JoinColumn アノテーションは、メインテーブルとの結合/リンク列を指定するために使用されます。ここで、 Project は関係の逆側にあるため、結合列は employee id で、 project id は逆結合列です。

Project クラスでは、 employees コレクションが所有者側の projects コレクションによってマップされることを示すために、 mappedBy 属性が @ ManyToMany アノテーションで使用されています。

5実行

多対多のアノテーションを実際に見るために、次のJUnitテストを書くことができます。

public class HibernateManyToManyAnnotationMainIntegrationTest {
    private static SessionFactory sessionFactory;
    private Session session;

   //...

    @Test
    public void givenData__whenInsert__thenCreatesMtoMrelationship() {
        String[]employeeData = { "Peter Oven", "Allan Norman" };
        String[]projectData = { "IT Project", "Networking Project" };
        Set<Project> projects = new HashSet<>();

        for (String proj : projectData) {
            projects.add(new Project(proj));
        }

        for (String emp : employeeData) {
            Employee employee = new Employee(emp.split(" ")[0],
              emp.split(" ")[1]);

            assertEquals(0, employee.getProjects().size());
            employee.setProjects(projects);
            session.persist(employee);

            assertNotNull(employee);
        }
    }

    @Test
    public void givenSession__whenRead__thenReturnsMtoMdata() {
        @SuppressWarnings("unchecked")
        List<Employee> employeeList = session.createQuery("FROM Employee")
          .list();

        assertNotNull(employeeList);

        for(Employee employee : employeeList) {
            assertNotNull(employee.getProjects());
        }
    }

   //...
}

データベースに作成された2つのエンティティ、 employee project 、および employee project__の各テーブル間の多対多の関係、および関係を表すサンプルデータを確認できます。

6. 結論

このチュートリアルでは、Hibernateの多対多アノテーションを使用してマッピングを作成する方法を説明しました。これは、XMLマッピングファイルを作成する場合よりも便利です。

このチュートリアルのソースコードはhttps://github.com/eugenp/tutorials/tree/master/persistence-modules/spring-hibernate-5[over on GitHub]にあります。