☰ See All Chapters |
JPA Many-to-Many Bidirectional Association Mapping
Many-To-Many mapping is an association between one many persistence object and many other related persistence object. In Many-To-Many mapping, relationship will be always bidirectional.
Let us consider persistence object A holding persistence objects X, Y, Z. persistence object Z can hold persistence objects M, N, O. Now these persistence objects M, N, O are related to persistence object Z. But not related to persistence object A. But persistence object Z is related to persistence object A. In this way it becomes conflict in keeping the relationship. To handle this situation in Many-To-Many Bidirectional Association Mapping, we take the support of third table called relationship table. This table maintains the relationship between records.
As an example, the association between Student and Course is a bidirectional many-to-many mapping. One Student can subscribe for many Course. One Course can be attended by many students. Student needs Course information and as well as Course needs Student information.
JPA Many-to-Many Bidirectional Association Mapping Example
Now let us see how this mapping is done in persistence class by going through an example. The following code shows how to do Many-To-Many bidirectional association mapping. We created two entities, Student and Course. In the Student class we annotate the collection of Course field by @ManyToMany annotation and also in Course class we annotate the collection Student field by @ ManyToMany annotation. Now either in Student or in Course we have annotate the collection of other persistence object with the annotation @JoinTable by specifying the relationship table. Here the relationship table is STUDENTCOURSE table, this maintains the relationship between records.
Database script (MySQL)
DROP TABLE STUDENTCOURSE; COMMIT;
DROP TABLE STUDENT; COMMIT;
DROP TABLE COURSE; COMMIT;
CREATE TABLE STUDENT( SID INT(5) PRIMARY KEY AUTO_INCREMENT, SNAME VARCHAR(30) );
CREATE TABLE COURSE( CID INT(5) PRIMARY KEY AUTO_INCREMENT, CNAME VARCHAR(30) );
CREATE TABLE STUDENTCOURSE( SID INT(5), CID INT(5), CONSTRAINT FOREIGN KEY (SID) REFERENCES STUDENT (SID), CONSTRAINT FOREIGN KEY (CID) REFERENCES COURSE (CID) ); |
pom.xml
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.java4coding</groupId> <artifactId>M2M_BidirectionalAssociationMapping</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>M2M_BidirectionalAssociationMapping</name> <url>https://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>javax.persistence</artifactId> <version>2.0.0</version> </dependency>
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>4.2.8.Final</version> </dependency>
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.11</version> </dependency> </dependencies> </project> |
persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="https://java.sun.com/xml/ns/persistence" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://java.sun.com/xml/ns/persistence https://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0">
<persistence-unit name="StudentPU"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/study" /> <property name="hibernate.connection.driver_class" value="com.mysql.cj.jdbc.Driver" /> <property name="hibernate.connection.username" value="root" /> <property name="hibernate.connection.password" value="root" /> <property name="hibernate.archive.autodetection" value="class" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <property name="hbm2ddl.auto" value="update" /> </properties> </persistence-unit> </persistence> |
Course.java
package com.java4coding;
import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.Table;
@Entity @Table(name = "COURSE") public class Course {
@Id @Column(name = "CID") @GeneratedValue(strategy=GenerationType.AUTO) private int cid;
@Column(name = "CNAME") private String cname;
@ManyToMany(mappedBy = "courses",cascade=CascadeType.ALL) private Set<Student> students;
public int getCid() { return this.cid; } public void setCid(int cid) { this.cid = cid; } public String getCname() { return this.cname; } public void setCname(String cname) { this.cname = cname; } public Set<Student> getStudents() { return this.students; } public void setStudents(Set<Student> students) { this.students = students; } } |
Student.java
package com.java4coding;
import java.util.Set;
import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table;
@Entity @Table(name = "STUDENT") public class Student {
@Id @Column(name = "SID") @GeneratedValue(strategy = GenerationType.AUTO) private int sid;
@Column(name = "SNAME") private String sname;
@ManyToMany(cascade = CascadeType.ALL) @JoinTable(name = "STUDENTCOURSE", joinColumns = { @JoinColumn(name = "SID") }, inverseJoinColumns = { @JoinColumn(name = "CID") }) private Set<Course> courses;
//setters and getters public int getSid() { return this.sid; } public void setSid(int sid) { this.sid = sid; } public String getSname() { return this.sname; } public void setSname(String sname) { this.sname = sname; } public Set<Course> getCourses() { return this.courses; } public void setCourses(Set<Course> courses) { this.courses = courses; } } |
Test.java
package com.java4coding;
import java.util.HashSet; import java.util.Set; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence;
public class Test { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("StudentPU"); EntityManager em = emf.createEntityManager();
em.getTransaction().begin(); Course c1 = new Course(); c1.setCname("JAVA");
Course c2 = new Course(); c2.setCname("SERVLET");
Course c3 = new Course(); c3.setCname("JSP");
Student s1 = new Student(); s1.setSname("Manu Manjunatha");
Student s2 = new Student(); s2.setSname("Advith Tyagraj");
Set<Course> sc = new HashSet<>(); sc.add(c1); sc.add(c2); sc.add(c3);
Set<Student> ss = new HashSet<>(); ss.add(s1); ss.add(s2);
// ASSOCIATING STUDENT WITH COURSE c1.setStudents(ss); c2.setStudents(ss); c3.setStudents(ss);
// ASSOCIATING COURSE WITH STUDENT s1.setCourses(sc); s2.setCourses(sc);
em.persist(s1); em.persist(s2); em.getTransaction().commit();
em.getTransaction().begin(); // STUDENT CAN ACCESS COURSE Student s = em.find(Student.class, 1); System.out.println("Student id is " + s.getSid()); System.out.println("Student name is " + s.getSname());
Set<Course> z = s.getCourses();
for (Course course : z) { System.out.println("This student has joined for following courses " + course.getCname()); }
// COURSE CAN ACCESS STUDENT Course c = em.find(Course.class, 1); System.out.println("Course id is " + c.getCid()); System.out.println("Course name is " + c.getCname());
Set<Student> students = c.getStudents();
for (Student stu : students) { System.out.println("Following students have joined for this course " + stu.getSname()); }
em.getTransaction().commit(); } } |
Project directory structure
Output:
Hibernate: insert into STUDENT (SNAME) values (?) Hibernate: insert into COURSE (CNAME) values (?) Hibernate: insert into STUDENT (SNAME) values (?) Hibernate: insert into COURSE (CNAME) values (?) Hibernate: insert into COURSE (CNAME) values (?) Hibernate: insert into STUDENTCOURSE (SID, CID) values (?, ?) Hibernate: insert into STUDENTCOURSE (SID, CID) values (?, ?) Hibernate: insert into STUDENTCOURSE (SID, CID) values (?, ?) Hibernate: insert into STUDENTCOURSE (SID, CID) values (?, ?) Hibernate: insert into STUDENTCOURSE (SID, CID) values (?, ?) Hibernate: insert into STUDENTCOURSE (SID, CID) values (?, ?) Student id is 1 Student name is Manu Manjunatha This student has joined for following courses SERVLET This student has joined for following courses JAVA This student has joined for following courses JSP Course id is 1 Course name is SERVLET Following students have joined for this course Advith Tyagraj Following students have joined for this course Manu Manjunatha |
All Chapters