Hibernate Many to Many Annotation Tutorial

1. Introduzione

In questo breve tutorial, daremo una rapida occhiata a come l' annotazione @ManyToMany può essere utilizzata per specificare questo tipo di relazioni in Hibernate.

2. Un tipico esempio

Cominciamo con un semplice diagramma di relazione tra entità, che mostra l'associazione molti-a-molti tra due entità dipendente e progetto:

In questo scenario, qualsiasi dipendente può essere assegnato a più progetti e un progetto può avere più dipendenti che lavorano per esso, portando a un'associazione molti-a-molti tra i due.

Abbiamo una tabella dei dipendenti con dipendente_id come chiave primaria e una tabella di progetto con project_id come chiave primaria. Per connettere entrambi i lati è necessario un join table employee_project .

3. Configurazione del database

Supponiamo di avere un database già creato con il nome spring_hibernate_many_to_many.

Abbiamo anche bisogno di creare le dipendenti e di progetto tavoli insieme alla employee_project uniamo tavolo con employee_id e project_id come chiavi esterne:

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; 

Con la configurazione del database, il passaggio successivo sarebbe la preparazione delle dipendenze Maven e la configurazione di Hibernate. Per informazioni su questo, fare riferimento all'articolo su Guide to Hibernate4 with Spring

4. Le classi del modello

Le classi modello Employee e Project devono essere create con annotazioni 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 }

Come possiamo vedere, sia la classe Employee che le classi Project si riferiscono l'una all'altra, il che significa che l'associazione tra di loro è bidirezionale.

Per mappare un'associazione molti a molti, utilizziamo le annotazioni @ManyToMany , @JoinTable e @JoinColumn . Diamo un'occhiata più da vicino a loro.

L' annotazione @ManyToMany viene utilizzata in entrambe le classi per creare la relazione molti-a-molti tra le entità.

Questa associazione ha due lati, cioè il lato proprietario e il lato inverso. Nel nostro esempio, il lato proprietario è Employee, quindi la tabella di join viene specificata sul lato proprietario utilizzando l' annotazione @JoinTable nella classe Employee . Il @JoinTable viene utilizzato per definire il join tavolo / link. In questo caso, è Employee_Project.

L' annotazione @JoinColumn viene utilizzata per specificare la colonna di unione / collegamento con la tabella principale. Qui, il join colonna è employee_id e project_id è l'inverso colonna di join dal progetto si trova sul lato inverso del rapporto.

Nella classe Project , l' attributo mappedBy viene utilizzato nell'annotazione @ManyToMany per indicare che la raccolta di impiegati è mappata dalla raccolta di progetti del lato proprietario.

5. Esecuzione

Per vedere l'annotazione molti-a-molti in azione, possiamo scrivere il seguente test 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()); } } // ... }

Possiamo vedere la relazione molti-a-molti tra le due entità create nel database: le tabelle dipendente , progetto e dipendente_progetto con dati di esempio che rappresentano la relazione.

6. Conclusione

In questo tutorial, abbiamo visto come creare mappature utilizzando le annotazioni molti-a-molti di Hibernate, che è una controparte più conveniente rispetto alla creazione di file di mappatura XML.

Il codice sorgente di questo tutorial può essere trovato su GitHub.