One To Many Mapping XML Mapping in Hibernate

Let us understand about One to Many XML Mapping in Hibernate


In this article, let’s discuss about Bidirectional one to Many relation mapping in Hibernate using XML

In this relation mapping, one object of a class is associated with multiple objects of another class.
In other words
One record of a table is associated with multiple records of another table.

In this mapping primary key of One side will become a foreign key in Many side

Example:

Consider Applicant and Address

One Applicant can have have multiple addresses like Permanent address and Current address.

Relation looks as below

OneToManyERD

As shown in the above ER diagram,Relation between Applicant and Address is One To Many.

Address_Id is the primary key for Address table

Applicant_Id is the primary key for Applicant table

We can see that Applicant_Id which is the primary key at One side(Applicant) has become the Foreign key on the Many side(Address).

Step 1

Create hibernate project

Please refer Hibernate setup in eclipse article on how to do it.

Project structure

OneToManyXMLProjStructure

Step 2

Update pom.xml with Hibernate and Mysql dependencies

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2.   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3.   <modelVersion>4.0.0</modelVersion>
  4.  
  5.   <groupId>OneToManyXML</groupId>
  6.   <artifactId>OneToManyXML</artifactId>
  7.   <version>0.0.1-SNAPSHOT</version>
  8.   <packaging>jar</packaging>
  9.  
  10.   <name>OneToManyXML</name>
  11.   <url>http://maven.apache.org</url>
  12.  
  13.   <properties>
  14.     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  15.   </properties>
  16.  
  17.   <dependencies>
  18.     <dependency>
  19.       <groupId>junit</groupId>
  20.       <artifactId>junit</artifactId>
  21.       <version>3.8.1</version>
  22.       <scope>test</scope>
  23.     </dependency>
  24.  
  25.      <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
  26.         <dependency>
  27.             <groupId>org.hibernate</groupId>
  28.             <artifactId>hibernate-core</artifactId>
  29.             <version>5.2.6.Final</version>
  30.         </dependency>
  31.         <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
  32.         <dependency>
  33.             <groupId>mysql</groupId>
  34.             <artifactId>mysql-connector-java</artifactId>
  35.             <version>6.0.5</version>
  36.         </dependency>
  37.   </dependencies>
  38. </project>
<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>

  <groupId>OneToManyXML</groupId>
  <artifactId>OneToManyXML</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>OneToManyXML</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>

     <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>5.2.6.Final</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>6.0.5</version>
		</dependency>
  </dependencies>
</project>

Step 3

Create Applicant class

  1. package com.kb.model;
  2.  
  3. import java.util.Set;
  4.  
  5. public class Applicant {
  6.     private int applicantId;
  7.     private String firstName;
  8.     private String lastName;
  9.     private int age;
  10.     private String education;
  11.     private Set<Address> addresses;
  12.    
  13.     public int getApplicantId() {
  14.         return applicantId;
  15.     }
  16.     public void setApplicantId(int applicantId) {
  17.         this.applicantId = applicantId;
  18.     }
  19.     public String getFirstName() {
  20.         return firstName;
  21.     }
  22.     public void setFirstName(String firstName) {
  23.         this.firstName = firstName;
  24.     }
  25.     public String getLastName() {
  26.         return lastName;
  27.     }
  28.     public void setLastName(String lastName) {
  29.         this.lastName = lastName;
  30.     }
  31.     public int getAge() {
  32.         return age;
  33.     }
  34.     public void setAge(int age) {
  35.         this.age = age;
  36.     }
  37.     public String getEducation() {
  38.         return education;
  39.     }
  40.     public void setEducation(String education) {
  41.         this.education = education;
  42.     }
  43.     public Set<Address> getAddresses() {
  44.         return addresses;
  45.     }
  46.     public void setAddresses(Set<Address> addresses) {
  47.         this.addresses = addresses;
  48.     }
  49.  
  50. }
package com.kb.model;

import java.util.Set;

public class Applicant {
	private int applicantId;
	private String firstName;
	private String lastName;
	private int age;
	private String education;
	private Set<Address> addresses;
	
	public int getApplicantId() {
		return applicantId;
	}
	public void setApplicantId(int applicantId) {
		this.applicantId = applicantId;
	}
	public String getFirstName() {
		return firstName;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getEducation() {
		return education;
	}
	public void setEducation(String education) {
		this.education = education;
	}
	public Set<Address> getAddresses() {
		return addresses;
	}
	public void setAddresses(Set<Address> addresses) {
		this.addresses = addresses;
	}

}


We can see that we have added Set< Address> in Applicant class to maintain OneToMany relation.

Step 4

Create Address class

  1. package com.kb.model;
  2.  
  3. public class Address {
  4.     private int addressId;
  5.     private String street;
  6.     private String city;
  7.     private String zipcode;
  8.     private Applicant applicant;
  9.     public int getAddressId() {
  10.         return addressId;
  11.     }
  12.     public void setAddressId(int addressId) {
  13.         this.addressId = addressId;
  14.     }
  15.     public String getStreet() {
  16.         return street;
  17.     }
  18.     public void setStreet(String street) {
  19.         this.street = street;
  20.     }
  21.     public String getCity() {
  22.         return city;
  23.     }
  24.     public void setCity(String city) {
  25.         this.city = city;
  26.     }
  27.     public String getZipcode() {
  28.         return zipcode;
  29.     }
  30.     public void setZipcode(String zipcode) {
  31.         this.zipcode = zipcode;
  32.     }
  33.     public Applicant getApplicant() {
  34.         return applicant;
  35.     }
  36.     public void setApplicant(Applicant applicant) {
  37.         this.applicant = applicant;
  38.     }
  39.  
  40. }
package com.kb.model;

public class Address {
	private int addressId;
	private String street;
	private String city;
	private String zipcode;
	private Applicant applicant;
	public int getAddressId() {
		return addressId;
	}
	public void setAddressId(int addressId) {
		this.addressId = addressId;
	}
	public String getStreet() {
		return street;
	}
	public void setStreet(String street) {
		this.street = street;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public String getZipcode() {
		return zipcode;
	}
	public void setZipcode(String zipcode) {
		this.zipcode = zipcode;
	}
	public Applicant getApplicant() {
		return applicant;
	}
	public void setApplicant(Applicant applicant) {
		this.applicant = applicant;
	}

}


We can see that we have added Applicant in Address class to maintain other side of OneToMany relation which is ManyToOne.

Step 5

Create applicant.hbm.xml

  1. <?xml version='1.0' encoding='UTF-8'?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC  
  3.           "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.           "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5.  
  6. <hibernate-mapping package="com.kb.model">
  7.     <class name="Applicant" table="Applicant">
  8.         <id name="applicantId" type="int">
  9.             <column name="Applicant_Id"></column>
  10.             <generator class="increment"></generator>
  11.         </id>
  12.         <property name="firstName" column="FirstName"></property>
  13.         <property name="lastName" column="LastName"></property>
  14.         <property name="age" type="int" column="Age"></property>
  15.         <property name="education" column="Education"></property>
  16.  
  17.         <set name="addresses" table="Address"
  18.                 inverse="true" lazy="true" fetch="select">
  19.             <key>
  20.                 <column name="Applicant_Id" not-null="true" />
  21.             </key>
  22.             <one-to-many class="Address" />
  23.         </set>
  24.     </class>
  25. </hibernate-mapping>  
<?xml version='1.0' encoding='UTF-8'?>  
<!DOCTYPE hibernate-mapping PUBLIC  
          "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.kb.model">
	<class name="Applicant" table="Applicant">
		<id name="applicantId" type="int">
			<column name="Applicant_Id"></column>
			<generator class="increment"></generator>
		</id>
		<property name="firstName" column="FirstName"></property>
		<property name="lastName" column="LastName"></property>
		<property name="age" type="int" column="Age"></property>
		<property name="education" column="Education"></property>

		<set name="addresses" table="Address" 
				inverse="true" lazy="true" fetch="select">
            <key>
                <column name="Applicant_Id" not-null="true" />
            </key>
            <one-to-many class="Address" />
        </set>
	</class>
</hibernate-mapping>  


In this mapping file,We have defined the Table mapping for Applicant class.

We have specified Primary key as applicantId and generator class as “increment” for automatic primary key generation.

We have defined One to Many mapping with Address entity using < set > and < one-to-many > tag.

We have also provided lazy = true to achieve lazy loading

fetch = select to inform hibernate to generate separate select query while retrieving addresses

inverse = true indicates that Address is the relationship owner.

Step 6

Create address.hbm.xml

  1. <?xml version='1.0' encoding='UTF-8'?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC  
  3.           "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  4.           "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5.  
  6. <hibernate-mapping package="com.kb.model">
  7.     <class name="Address" table="Address">
  8.  
  9.         <id name="addressId" type="int">
  10.             <column name="Address_Id" />
  11.             <generator class="increment" />
  12.         </id>
  13.  
  14.         <property name="street" column="Street" />
  15.         <property name="city" column="City" />
  16.         <property name="zipcode" column="Zipcode" />
  17.         <many-to-one name="applicant" class="Applicant" fetch="select">
  18.             <column name="Applicant_Id" not-null="true" />
  19.         </many-to-one>
  20.     </class>
  21. </hibernate-mapping>  
<?xml version='1.0' encoding='UTF-8'?>  
<!DOCTYPE hibernate-mapping PUBLIC  
          "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.kb.model">
	<class name="Address" table="Address">

		<id name="addressId" type="int">
			<column name="Address_Id" />
			<generator class="increment" />
		</id>

		<property name="street" column="Street" />
		<property name="city" column="City" />
		<property name="zipcode" column="Zipcode" />
		<many-to-one name="applicant" class="Applicant" fetch="select">
            <column name="Applicant_Id" not-null="true" />
        </many-to-one>
	</class>
</hibernate-mapping>  


In this mapping file,We have defined the Table mapping for Address class.

We have specified Primary key as addressId and generator class as “increment”.

We have defined Many to One mapping with Applicant entity using < many-to-one > tag as in Many Addresses belongs to one Employee..

We have also provided fetch=select to inform hibernate to generate separate select query while retrieving Applicant(used for lazy loading)

Step 7

Create hibernate.cfg.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-configuration PUBLIC
  3.        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  4.        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
  5.  
  6. <hibernate-configuration>
  7.  
  8.    <session-factory>
  9.  
  10.        <!-- Database connection properties -->
  11.        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
  12.        <property name="connection.url">jdbc:mysql://localhost/javainsimpleway</property>
  13.        <property name="connection.username">root</property>
  14.        <property name="connection.password">root</property>
  15.  
  16.        <!-- JDBC connection pool (using the built-in) -->
  17.        <property name="connection.pool_size">10</property>
  18.  
  19.        <!-- SQL dialect -->
  20.        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
  21.  
  22.        <!-- Disable the second-level cache -->
  23.        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
  24.  
  25.        <!-- Echo all executed SQL to stdout -->
  26.        <property name="show_sql">true</property>
  27.        
  28.        <!-- Format the generated Sql -->
  29.        <property name="format_sql">true</property>
  30.  
  31.        <!-- Dont Drop and re-create the database schema on startup,Just update it -->
  32.        <property name="hbm2ddl.auto">update</property>
  33.  
  34. <mapping resource="com/kb/mapping/applicant.hbm.xml"/>
  35. <mapping resource="com/kb/mapping/address.hbm.xml"/>  
  36.  </session-factory>
  37.  
  38. </hibernate-configuration>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
       "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
       "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 
<hibernate-configuration>
 
   <session-factory>
 
       <!-- Database connection properties -->
       <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
       <property name="connection.url">jdbc:mysql://localhost/javainsimpleway</property>
       <property name="connection.username">root</property>
       <property name="connection.password">root</property>
 
       <!-- JDBC connection pool (using the built-in) -->
       <property name="connection.pool_size">10</property>
 
       <!-- SQL dialect -->
       <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
 
       <!-- Disable the second-level cache -->
       <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
 
       <!-- Echo all executed SQL to stdout -->
       <property name="show_sql">true</property>
       
       <!-- Format the generated Sql -->
       <property name="format_sql">true</property>
 
       <!-- Dont Drop and re-create the database schema on startup,Just update it -->
       <property name="hbm2ddl.auto">update</property>
 
<mapping resource="com/kb/mapping/applicant.hbm.xml"/>
<mapping resource="com/kb/mapping/address.hbm.xml"/>  
 </session-factory>
 
</hibernate-configuration>


We have defined all the database configuration in this file

hbm2ddl.auto property is defined in the config file which helps in automatic creation of tables in the database based on the mapping.

We have also provided the mapping xml file location using < mapping > tag.

Step 8

Create Hibernate util class

  1. package com.kb.util;
  2.  
  3. import org.hibernate.SessionFactory;
  4. import org.hibernate.cfg.Configuration;
  5.  
  6. public class HibernateUtil {
  7.     private static final SessionFactory sessionFactory = buildSessionFactory();
  8.  
  9.     private static SessionFactory buildSessionFactory() {
  10.         try {
  11.             // Create the SessionFactory from hibernate.cfg.xml
  12.             return new Configuration().configure().buildSessionFactory();
  13.         } catch (Throwable ex) {
  14.             // Make sure you log the exception to track it
  15.             System.err.println("SessionFactory creation failed." + ex);
  16.             throw new ExceptionInInitializerError(ex);
  17.         }
  18.     }
  19.  
  20.     public static SessionFactory getSessionFactory() {
  21.         return sessionFactory;
  22.     }
  23.    
  24.     public static void shutdown() {
  25.         // Optional but can be used to Close caches and connection pools
  26.         getSessionFactory().close();
  27.     }
  28.  
  29. }
package com.kb.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
	private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            return new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            // Make sure you log the exception to track it
            System.err.println("SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
    
    public static void shutdown() {
    	// Optional but can be used to Close caches and connection pools
    	getSessionFactory().close();
    }

}

Step 9

Create main class to interact with DB

  1. package com.kb.db;
  2.  
  3. import org.hibernate.Session;
  4. import org.hibernate.SessionFactory;
  5. import org.hibernate.Transaction;
  6.  
  7. import com.kb.model.Address;
  8. import com.kb.model.Applicant;
  9. import com.kb.util.HibernateUtil;
  10.  
  11. public class Main {
  12.     public static void main(String[] args) {
  13.         // Get session factory using Hibernate Util class
  14.         SessionFactory sf = HibernateUtil.getSessionFactory();
  15.         // Get session from Sesson factory
  16.         Session session = sf.openSession();
  17.  
  18.         // Begin transaction
  19.         Transaction t = session.beginTransaction();
  20.        
  21.         //Create Applicant Model data
  22.         Applicant applicant = new Applicant();
  23.         applicant.setFirstName("John");
  24.         applicant.setLastName("KC");
  25.         applicant.setAge(28);
  26.         applicant.setEducation("Graduation");
  27.  
  28.         //Create Passport Model data
  29.         Address currentAdd = new Address();
  30.         currentAdd.setStreet("Royal road");
  31.         currentAdd.setCity("Newyork");
  32.         currentAdd.setZipcode("10001");
  33.        
  34.         //Associate Applicant to  current Address
  35.         currentAdd.setApplicant(applicant);
  36.        
  37.         Address permanentAdd = new Address();
  38.         permanentAdd.setStreet("Manyar Road");
  39.         permanentAdd.setCity("Sydney");
  40.         permanentAdd.setZipcode("2060");
  41.        
  42.         //Associate Applicant to permanent Address
  43.         permanentAdd.setApplicant(applicant);
  44.        
  45.         session.persist(applicant);
  46.         session.persist(currentAdd);
  47.         session.persist(permanentAdd);
  48.  
  49.         // Commit the transaction and close the session
  50.         t.commit();
  51.         session.close();
  52.         System.out.println("successfully persisted Applicant details");
  53.     }
  54.  
  55. }
package com.kb.db;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import com.kb.model.Address;
import com.kb.model.Applicant;
import com.kb.util.HibernateUtil;

public class Main {
	public static void main(String[] args) {
		// Get session factory using Hibernate Util class
		SessionFactory sf = HibernateUtil.getSessionFactory();
		// Get session from Sesson factory
		Session session = sf.openSession();

		// Begin transaction
		Transaction t = session.beginTransaction();
		
		//Create Applicant Model data
		Applicant applicant = new Applicant();
		applicant.setFirstName("John");
		applicant.setLastName("KC");
		applicant.setAge(28);
		applicant.setEducation("Graduation");

		//Create Passport Model data
		Address currentAdd = new Address();
		currentAdd.setStreet("Royal road");
		currentAdd.setCity("Newyork");
		currentAdd.setZipcode("10001");
		
		//Associate Applicant to  current Address
		currentAdd.setApplicant(applicant);
		
		Address permanentAdd = new Address();
		permanentAdd.setStreet("Manyar Road");
		permanentAdd.setCity("Sydney");
		permanentAdd.setZipcode("2060");
		
		//Associate Applicant to permanent Address
		permanentAdd.setApplicant(applicant);
		
		session.persist(applicant);
		session.persist(currentAdd);
		session.persist(permanentAdd);

		// Commit the transaction and close the session
		t.commit();
		session.close();
		System.out.println("successfully persisted Applicant details");
	}

}


We have added 1 Applicant and associated 2 addresses to it and saved those details

Step 10

Run the above class to check the output

Hibernate: 
    
    create table Address (

       Address_Id integer not null,

        Street varchar(255),

        City varchar(255),

        Zipcode varchar(255),

        Applicant_Id integer not null,

        primary key (Address_Id)
    )


Hibernate: 
    

    create table Applicant (

       Applicant_Id integer not null,

        FirstName varchar(255),

        LastName varchar(255),

        Age integer,

        Education varchar(255),

        primary key (Applicant_Id)
    )


Hibernate: 
    

    alter table Address 

       add constraint FKap8oxrnisp4tun1nbfel49gj4 

       foreign key (Applicant_Id) 

       references Applicant (Applicant_Id)


Hibernate: 


    select
        max(Applicant_Id) 

    from
        Applicant


Hibernate: 


    select
        max(Address_Id) 

    from
        Address


Hibernate: 


    insert 

    into
        Applicant
        (FirstName, LastName, Age, Education, Applicant_Id) 

    values
        (?, ?, ?, ?, ?)


Hibernate: 


    insert 

    into
        Address
        (Street, City, Zipcode, Applicant_Id, Address_Id) 

    values
        (?, ?, ?, ?, ?)


Hibernate: 

    insert 

    into
        Address
        (Street, City, Zipcode, Applicant_Id, Address_Id) 

    values
        (?, ?, ?, ?, ?)

successfully persisted Applicant details


We can see that Create statement is executed for creating both Applicant and Address tables.

We can see that Foreign key constraint is created on Address table referencing the primary key of Applicant table..

3 insert statements are executed (one for Applicant and two for Addresses).

Check Table in MYSQL console

E:\MySql_Install\bin
Mysql –u root –p
Enter password

Use javainsimpleway;

Select * from Applicant;

Select * from address;

OneToManyXMLOutput

We can see that primary key of Applicant table is associated with multiple Address Records as a foreign key.

Note: Remember,In One To Many relation,foreign key constraint will always be added at the Many side.


Download this project OneToManyXML.zip

About the Author

Founder of javainsimpleway.com
I love Java and open source technologies and very much passionate about software development.
I like to share my knowledge with others especially on technology 🙂
I have given all the examples as simple as possible to understand for the beginners.
All the code posted on my blog is developed,compiled and tested in my development environment.
If you find any mistakes or bugs, Please drop an email to kb.knowledge.sharing@gmail.com

Connect with me on Facebook for more updates

Share this article on