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

多対多の注釈チュートリアルを休止状態にする

1. 前書き

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

2. 典型的な例

簡単な実体関連図から始めましょう。これは、2つの実体employeeproject:の間の多対多の関連を示しています。

image

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

主キーとしてemployee_idを持つemployeeテーブルと、主キーとしてproject_idを持つprojectテーブルがあります。 ここでは、両側を接続するために結合テーブルemployee_projectが必要です。

3. データベースのセットアップ

spring_hibernate_many_to_many.という名前のデータベースがすでに作成されていると仮定します。

また、employeeテーブルとprojectテーブルを、外部キーとしてemployee_idproject_idを使用して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構成の準備です。 これについては、Guide to Hibernate4 with Springの記事を参照してください。

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 projects = new HashSet<>();

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

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

    // standard constructors/getters/setters
}

ご覧のとおり、both the Employee class and Project classes refer to one another, which means that the association between them is bidirectional.

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

@ManyToManyアノテーションは、エンティティ間に多対多の関係を作成するために両方のクラスで使用されます。

This association has two sides i.e. the owning side and the inverse side.この例では、所有側はEmployeeであるため、結合テーブルは、Employeeクラスの@JoinTableアノテーションを使用して所有側で指定されます。 @JoinTableは、結合/リンクテーブルを定義するために使用されます。 この場合、それはEmployee_Project.です。

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

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

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 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 employeeList = session.createQuery("FROM Employee")
          .list();

        assertNotNull(employeeList);

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

    // ...
}

データベースで作成された2つのエンティティ(employeeproject、およびemployee_projectテーブル)間の多対多の関係と、関係を表すサンプルデータを確認できます。

6. 結論

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

このチュートリアルのソースコードはover on GitHubにあります。