Tutoriel de mise en veille prolongée d'annotations plusieurs à plusieurs

1. Introduction

Dans ce rapide tutoriel, nous verrons rapidement comment l' annotation @ManyToMany peut être utilisée pour spécifier ce type de relations dans Hibernate.

2. Un exemple typique

Commençons par un simple diagramme de relation d'entité - qui montre l'association plusieurs-à-plusieurs entre deux entités, employé et projet:

Dans ce scénario, n'importe quel employé donné peut être affecté à plusieurs projets et un projet peut avoir plusieurs employés travaillant pour lui, conduisant à une association plusieurs-à-plusieurs entre les deux.

Nous avons une table employee avec employee_id comme clé primaire et une table project avec project_id comme clé primaire. Une table de jointure employee_project est requise ici pour connecter les deux côtés.

3. Configuration de la base de données

Supposons que nous ayons une base de données déjà créée avec le nom spring_hibernate_many_to_many.

Nous devons aussi créer les employés et projets tables ainsi que la EMPLOYEE_PROJECT table de jointure avec employee_id et project_id comme clés étrangères:

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; 

Une fois la base de données configurée, la prochaine étape serait la préparation des dépendances Maven et de la configuration Hibernate. Pour plus d'informations à ce sujet, reportez-vous à l'article sur le Guide d'Hibernate4 avec Spring

4. Les classes modèles

Les classes de modèle Employee et Project doivent être créées avec des annotations 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 }

Comme nous pouvons le voir, la classe Employee et les classes Project se réfèrent l'une à l'autre, ce qui signifie que l'association entre elles est bidirectionnelle.

Afin de mapper une association plusieurs-à-plusieurs, nous utilisons les annotations @ManyToMany , @JoinTable et @JoinColumn . Regardons-les de plus près.

L' annotation @ManyToMany est utilisée dans les deux classes pour créer la relation plusieurs-à-plusieurs entre les entités.

Cette association a deux côtés, à savoir le côté propriétaire et le côté inverse. Dans notre exemple, le côté propriétaire est Employee, donc la table de jointure est spécifiée du côté propriétaire à l'aide de l' annotation @JoinTable dans la classe Employee . La @JoinTable est utilisée pour définir la table de jointure / liaison. Dans ce cas, il s'agit de Employee_Project.

L' annotation @JoinColumn est utilisée pour spécifier la colonne de jointure / liaison avec la table principale. Ici, la colonne de jointure est employee_id et project_id est la colonne de jointure inverse puisque Project est du côté inverse de la relation.

Dans la classe Project , l' attribut mappedBy est utilisé dans l' annotation @ManyToMany pour indiquer que la collection employés est mappée par la collection projects du côté propriétaire.

5. Exécution

Afin de voir l'annotation plusieurs-à-plusieurs en action, nous pouvons écrire le test JUnit suivant:

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()); } } // ... }

Nous pouvons voir la relation plusieurs-à-plusieurs entre les deux entités créées dans la base de données: les tables employee , project et employee_project avec des exemples de données représentant la relation.

6. Conclusion

Dans ce didacticiel, nous avons vu comment créer des mappages à l'aide des annotations plusieurs à plusieurs d'Hibernate, ce qui est un équivalent plus pratique que la création de fichiers de mappage XML.

Le code source de ce tutoriel se trouve à l'adresse over sur GitHub.