Quick Contact

    Hibernate

    Hibernate Many to Many Annotation Mapping Example

    In many-to-many association, the source entity has a field that stores a collection of target entities. The @ManyToMany JPA annotation is used to link the source entity with the target entity.

    A many-to-many association always uses an intermediate join table to store the association that joins two entities. The join table is defined using the @JoinTable JPA annotation.

    The many-to-many relationship is implemented using a third table called employees_projects which contains the details of the employees and their associated projects. Note that here Employee is a primary entity.

    1. Create a Simple Maven Project

      Use How to Create a Simple Maven Project in Eclipse article to create a simple Maven project in Eclipse IDE.

    2. Project Directory Structure

      Let’s create a packaging structure for the above created a simple maven project. Refer below screenshot for your reference.

    3. POM Dependencies

      We are using MySQL database so add MySQL dependency to pom.xml:

      < 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      < modelVersion>4.0.0< /modelVersion>
      < parent>
      < groupId>net.ducatindia.hibernate< /groupId>
      < artifactId>hibernate-tutorial< /artifactId>
      < version>0.0.1-SNAPSHOT< /version>
      < /parent>
      < artifactId>hibernate-many-to-many-example< /artifactId>
      < properties>
      < project.build.sourceEncoding>UTF-8< /project.build.sourceEncoding>
      < /properties>
      < dependencies>
      < !-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
      < dependency>
      < groupId>mysql< /groupId>
      < artifactId>mysql-connector-java< /artifactId>
      < version>8.0.13< /version>
      < /dependency>
      < !-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
      < dependency>
      < groupId>org.hibernate< /groupId>
      < artifactId>hibernate-core< /artifactId>
      < version>5.3.7.Final< /version>
      < /dependency>
      < /dependencies>
      < build>
      < sourceDirectory>src/main/java< /sourceDirectory>
      < plugins>
      < plugin>
      < artifactId>maven-compiler-plugin< /artifactId>
      < version>3.5.1< /version>
      < configuration>
      < source>1.8< /source>
      < target>1.8< /target>
      < /configuration>
      < /plugin>
      < /plugins>
      < /build>
      < /project>
      
    4. Creating the JPA Entities(Persistent classes)

      Let’s create JPA entities that we map with database tables. We use @ManyToMany annotation to create a many-to-many relationship between two entities. In a bi-directional association, the @ManyToMany annotation is used on both the entities but only one entity can be the owner of the relationship.

      Employee

      importjava.util.HashSet;
      importjava.util.Set;
      
      importjavax.persistence.CascadeType;
      importjavax.persistence.Column;
      importjavax.persistence.Entity;
      importjavax.persistence.GeneratedValue;
      importjavax.persistence.GenerationType;
      importjavax.persistence.Id;
      importjavax.persistence.JoinColumn;
      importjavax.persistence.JoinTable;
      importjavax.persistence.ManyToMany;
      importjavax.persistence.Table;
      
      @Entity
      @Table(name="employees")
      publicclassEmployee {
      
      privatestaticfinallongserialVersionUID=1L;
      
      @Id
      @Column(name="employee_id")
      @GeneratedValue(strategy=GenerationType.IDENTITY)
      privateLongemployeeId;
      
      @Column(name="first_name")
      privateStringfirstName;
      
      @Column(name="last_name")
      privateStringlastName;
      
      @ManyToMany(cascade= {
      CascadeType.ALL
          })
      @JoinTable(
      name="employees_projects",
      joinColumns= {
      @JoinColumn(name="employee_id")
              },
      inverseJoinColumns= {
      @JoinColumn(name="project_id")
              }
          )
      Set< Project> projects =newHashSet< Project> ();
      
      
      publicEmployee() {
      super();
          }
      
      publicEmployee(StringfirstName, StringlastName) {
      this.firstName=firstName;
      this.lastName=lastName;
          }
      
      publicEmployee(StringfirstName, StringlastName, Set< Project>projects) {
      this.firstName=firstName;
      this.lastName=lastName;
      this.projects= projects;
          }
      
      
      publicLonggetEmployeeId() {
      returnemployeeId;
          }
      
      publicvoidsetEmployeeId(LongemployeeId) {
      this.employeeId=employeeId;
          }
      
      publicStringgetFirstName() {
      returnfirstName;
          }
      
      publicvoidsetFirstName(StringfirstName) {
      this.firstName=firstName;
          }
      
      publicStringgetLastName() {
      returnlastName;
          }
      
      publicvoidsetLastName(StringlastName) {
      this.lastName=lastName;
          }
      
      publicSet< Project>getProjects() {
      return projects;
          }
      
      publicvoidsetProjects(Set< Project>projects) {
      this.projects= projects;
          }
      }
      

      Project

      importjava.util.HashSet;
      importjava.util.Set;
      
      importjavax.persistence.CascadeType;
      importjavax.persistence.Column;
      importjavax.persistence.Entity;
      importjavax.persistence.GeneratedValue;
      importjavax.persistence.Id;
      importjavax.persistence.ManyToMany;
      importjavax.persistence.Table;
      
      @Entity
      @Table(name="projects")
      publicclassProject {
      
      privatestaticfinallongserialVersionUID=1L;
      
      @Id
      @Column(name="project_id")
      @GeneratedValue
      privateLongprojectId;
      
      @Column(name="title")
      privateString title;
      
      @ManyToMany(mappedBy="projects", cascade= { CascadeType.ALL })
      privateSet< Employee> employees =newHashSet< Employee>();
      
      publicProject() {
      super();
          }
      
      publicProject(Stringtitle) {
      this.title= title;
          }
      
      publicLonggetProjectId() {
      returnprojectId;
          }
      
      publicvoidsetProjectId(LongprojectId) {
      this.projectId=projectId;
          }
      
      publicStringgetTitle() {
      return title;
          }
      
      publicvoidsetTitle(Stringtitle) {
      this.title= title;
          }
      
      publicSet< Employee>getEmployees() {
      return employees;
          }
      
      publicvoidsetEmployees(Set< Employee>employees) {
      this.employees= employees;
          }
      }
      

      Understanding JPA annotations used

      Let’s understand the JPA annotations used in above Employee and Project JPA entities:

      • @Entity – This annotation specifies that the class is an entity.
      • @Table – This annotation specifies the table in the database with which this entity is mapped.
      • @Id – This annotation specifies the primary key of the entity.
      • @GeneratedValue – This annotation specifies the generation strategies for the values of primary keys.
      • @Column – The @Column annotation is used to specify the mapping between a basic entity attribute and the database table column.
      • @ManyToMany – The @ManyToMany annotation is used to specify a many-to-many database relationship.
      • @JoinColumn – The @JoinColumn annotation is used to specify the FOREIGN KEY column used when joining an entity association or an embeddable collection.
      • @JoinColumns – The @JoinColumns annotation is used to group multiple @JoinColumn annotations, which are used when mapping entity association or an embeddable collection using a composite identifier.
      • @JoinTable – The @JoinTable annotation is used to specify the link table between two other database tables.
    5. Create a Hibernate configuration file – hibernate.cfg.xml

      The configuration file contains information about the database and mapping file. Conventionally, its name should be hibernate.cfg.xml.

      Let’s create an XML file named hibernate.cfg.xml under the resources folder and write the following code in it.

      < !DOCTYPEhibernate-configuration PUBLIC
              "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
              "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
      < hibernate-configuration>
      < session-factory>
      < !-- JDBC Database connection settings -->
      < propertyname="connection.driver_class">com.mysql.cj.jdbc.Driver< /property>
      < propertyname="connection.url">jdbc:mysql://localhost:3306/java_demo?useSSL=false< /property>
      < propertyname="connection.username">root
      < propertyname="connection.password">root< /property>
      < !-- Select our SQL dialect -->
      < propertyname="dialect">org.hibernate.dialect.MySQL5Dialect< /property>
      < !-- Echo the SQL to stdout -->
      < propertyname="show_sql">true< /property>
      < !-- Set the current session context -->
      < propertyname="current_session_context_class">thread< /property>
      < !-- Drop and re-create the database schema on startup -->
      < propertyname="hbm2ddl.auto">create-drop< /property>
      < mappingclass="net.ducatindia.hibernate.entity.Employee"/>
      < mappingclass="net.ducatindia.hibernate.entity.Project"/>
      < /session-factory>
      < /hibernate-configuration>
      
    6. Create a Hibernate utility Class

      Create a helper class to bootstrap hibernate SessionFactory. In most Hibernate applications, the SessionFactory should be instantiated once during application initialization. The single instance should then be used by all code in a particular process, and any Session should be created using this single SessionFactory.

      The SessionFactory is thread-safe and can be shared; a Session is a single-threaded object. Let’s create a HibernateUtil class to configure singleton SessionFactory and use it throughout the application.

      The bootstrapping API is quite flexible, but in most cases, it makes the most sense to think of it as a 3 step process:

      1. Build the StandardServiceRegistry
      2. Build the Metadata
      3. Use those 2 to build the SessionFactory
      importorg.hibernate.SessionFactory;
      importorg.hibernate.boot.Metadata;
      importorg.hibernate.boot.MetadataSources;
      importorg.hibernate.boot.registry.StandardServiceRegistry;
      importorg.hibernate.boot.registry.StandardServiceRegistryBuilder;
      
      publicclassHibernateUtil {
      privatestaticStandardServiceRegistry registry;
      privatestaticSessionFactorysessionFactory;
      
      publicstaticSessionFactorygetSessionFactory() {
      if (sessionFactory==null) {
      try {
      // Create registry
      registry=newStandardServiceRegistryBuilder().configure().build();
      
      // Create MetadataSources
      MetadataSources sources =newMetadataSources(registry);
      
      // Create Metadata
      Metadatametadata=sources.getMetadataBuilder().build();
      
      // Create SessionFactory
      sessionFactory=metadata.getSessionFactoryBuilder().build();
      
                  } catch (Exception e) {
      e.printStackTrace();
      if (registry !=null) {
      StandardServiceRegistryBuilder.destroy(registry);
                      }
                  }
              }
      returnsessionFactory;
          }
      
      publicstaticvoidshutdown() {
      if (registry !=null) {
      StandardServiceRegistryBuilder.destroy(registry);
              }
          }
      }
      
    7. Test Application

      packagenet.ducatindia.hibernate.test;
      
      importorg.hibernate.Session;
      
      importnet.ducatindia.hibernate.entity.Employee;
      importnet.ducatindia.hibernate.entity.Project;
      importnet.ducatindia.hibernate.util.HibernateUtil;
      
      publicclassTest {
      publicstaticvoidmain(String[] args) {
      Sessionsession=HibernateUtil.getSessionFactory().openSession();
      session.beginTransaction();
      
      // Create an employee
      Employeeemployee=newEmployee();
      employee.setFirstName("Ramesh");
      employee.setLastName("Fadatare");
      
      // Create project1
      Projectproject=newProject();
      project.setTitle("Employee Management System");
      
      // Create project2
      Project project1 =newProject();
      project1.setTitle("Content Management System");
      
      // employee can work on two projects, Add project references in the employee
      employee.getProjects().add(project);
      employee.getProjects().add(project1);
      
      // Add employee reference in the projects
      project.getEmployees().add(employee);
      project1.getEmployees().add(employee);
      
      session.save(employee);
      
      session.getTransaction().commit();
      HibernateUtil.shutdown();
          }
      }
      

      Output:

      The hibernate will generate below SQL statements for insert queries:

      Hibernate: insertinto employees (first_name, last_name) values (?, ?)
      Hibernate: insertinto projects (title, project_id) values (?, ?)
      Hibernate: insertinto projects (title, project_id) values (?, ?)
      Hibernate: insertintoemployees_projects (employee_id, project_id) values (?, ?)
      Hibernate: insertintoemployees_projects (employee_id, project_id) values (?, ?)
      

    Apply now for Advanced Java Training Course

    Copyright 1999- Ducat Creative, All rights reserved.

    Anda bisa mendapatkan server slot online resmi dan terpercaya tentu saja di sini. Sebagai salah satu provider yang menyediakan banyak pilihan permainan.