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]にあります。