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