Project Implementation of JPA Many-To-Many Mapping

Below are the steps to implement many-to-many mapping in JPA.

Step 1: Create the new JPA project using the InteljIdea named as jpa-many-to-many-mapping-demo.

Step 2: Open open.xml and add the below dependencies into the XML file.

Dependencies:

  <dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.0.2.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>

Project Structure:

After creating the Project, the folder structure will look like below:


Step 3: Open persistence.xml and put the below code into the project to configure the database.

XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
             version="3.0">
    <persistence-unit name="jpa-example">
        <class>model.Course</class>
        <class>model.Student</class>
        <class>service.CourseService</class>
        <class>service.StudentService</class>
        <properties>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/example"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value=""/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>

    </persistence-unit>
</persistence>


Step 4: Create a Java package named model and in that package create a Entity class named Student.

Go to src > main > java > model > Student and put the below code.

Java
package model;

import jakarta.persistence.*;

import java.util.HashSet;
import java.util.Set;

@Entity
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @ManyToMany(mappedBy = "students")
    private Set<Course> courses = new HashSet<>();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Course> getCourses() {
        return courses;
    }

    public void setCourses(Set<Course> courses) {
        this.courses = courses;
    }
}


Step 5: Create a new Entity class named Course.

Go to src > main > java > model > Course and put the below code.

Java
package model;

import jakarta.persistence.*;

import java.util.HashSet;
import java.util.Set;

@Entity
public class Course {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @ManyToMany
    @JoinTable(
            name = "course_student",
            joinColumns = @JoinColumn(name = "course_id"),
            inverseJoinColumns = @JoinColumn(name = "student_id")
    )
    private Set<Student> students = new HashSet<>();
    // Getters and Setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Student> getStudents() {
        return students;
    }

    public void setStudents(Set<Student> students) {
        this.students = students;
    }
}


Step 6: Create a new Java package named as service. In that package, create a new Entity Java class named StudentService.

Go to src > main > java > service > StudentService and put the below code.

Java
package service;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import model.Student;

import java.util.List;

public class StudentService {
    private EntityManager entityManager;

    public StudentService(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public List<Student> getAllStudents() {
        return entityManager.createQuery("SELECT s FROM Student s", Student.class).getResultList();
    }

    @Transactional
    public Student saveStudent(Student student) {
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        entityManager.persist(student);
        transaction.commit();
        return student;
    }

    public Student getStudentById(Long id) {
        return entityManager.find(Student.class, id);
    }  
}


Step 7: Create a new Entity Java class named CourseService .

Go to src > main > java > service > CourseService and put the below code.

Java
package service;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import model.Course;

import java.util.List;
@Transactional
public class CourseService {
    private EntityManager entityManager;

    public CourseService(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public List<Course> getAllCourses() {
        return entityManager.createQuery("SELECT c FROM Course c", Course.class).getResultList();
    }


    public Course saveCourse(Course course) {
        EntityTransaction transaction = entityManager.getTransaction();
        transaction.begin();
        entityManager.persist(course);
        transaction.commit();
        return course;
    }

    public Course getCourseById(Long id) {
        return entityManager.find(Course.class, id);
    }  
}


Step 8: Create a new Java class named as the MainApplication.

Go to src > main > java > MainApplication and write the below code..

Java
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
import model.Course;
import model.Student;
import service.CourseService;
import service.StudentService;

import java.util.List;

public class MainApplication {
    public static void main(String[] args) {
        // Create EntityManagerFactory using persistence unit name defined in persistence.xml
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("jpa-example");

        // Instantiate services
        CourseService courseService = new CourseService(entityManagerFactory.createEntityManager());
        StudentService studentService = new StudentService(entityManagerFactory.createEntityManager());

        // Add some courses
        Course mathCourse = new Course();
        mathCourse.setName("Java");
        courseService.saveCourse(mathCourse);

        Course scienceCourse = new Course();
        scienceCourse.setName("Python");
        courseService.saveCourse(scienceCourse);

        // Add some students
        Student johnStudent = new Student();
        johnStudent.setName("Mahesh Kadambala");
        johnStudent.getCourses().add(mathCourse);
        johnStudent.getCourses().add(scienceCourse);
        studentService.saveStudent(johnStudent);

        Student aliceStudent = new Student();
        aliceStudent.setName("Eswar Beta");
        aliceStudent.getCourses().add(mathCourse);
        studentService.saveStudent(aliceStudent);

        // Retrieve and print courses
        List<Course> courses = courseService.getAllCourses();
        System.out.println("Courses:");
        for (Course course : courses) {
            System.out.println(course.getId() + ": " + course.getName());
        }

        // Retrieve and print students
        List<Student> students = studentService.getAllStudents();
        System.out.println("\nStudents:");
        for (Student student : students) {
            System.out.println(student.getId() + ": " + student.getName());
            System.out.println("Courses:");
            for (Course course : student.getCourses()) {
                System.out.println(" - " + course.getName());
            }
        }

        // Close the EntityManagerFactory when done
        entityManagerFactory.close();
    }
}
  • The MainApplication class initializes an EntityManagerFactory based on the persistence unit defined in persistence.xml.
  • Then it instantiates CourseService and StudentService to manage course and student entities respectively.
  • Courses and students are added to the database, and then retrieved and printed.
  • Finally, the EntityManagerFactory is closed to release resources.

pom.xml:

XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>jpa-many-to-many-mapping-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>jpa-many-to-many-mapping-demo</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.source>11</maven.compiler.source>
        <junit.version>5.9.2</junit.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.hibernate.orm</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>6.0.2.Final</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>3.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
        </plugins>
    </build>
</project>


Step 9: Once the project is completed, run the application. After running, it will show the courses and Students with courses as output. Refer the below image for the better understanding of the concept.

By the following these steps and the understanding the annotations involved, developers can be effectively implement and manage the many-to-many relationships in the JPA application.



JPA – Many-To-Many Mapping

JPA Many-To-Many Mapping provides the many-to-many relationship representing the association between the two entities where each instance of the one entity can be associated with the multiple instances of the other entity.

Many-to-many mapping is used when multiple instances of one entity are associated with multiple instances of another entity, and it forms the many-to-many relationship. In database terms, it can be typically implemented using the join table that links the primary keys of both entities.

Similar Reads

Steps to Implement Many-To-Many Mapping in JPA

1. Define the entities involved in the relationship....

Project Implementation of JPA Many-To-Many Mapping

Below are the steps to implement many-to-many mapping in JPA....