One to One XML Mapping in Hibernate

Let us understand about One to One XML Mapping in Hibernate


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

In this mapping, both the tables will share the common primary key.

Example:

Consider the relation between Applicant and Passport

One Applicant will have only one Passport.

Let’s develop One To One relation between Applicant and Passport

Relation looks as below

OneToOne_ERD

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

Passport_Id column is the primary key of Passport table

Applicant_Id column is the primary key of Applicant table

Note:
Both Applicant and Passport tables will share the same value for primary key. Hence Applicant_Id and Passport_Id will have the same value for each record.

Step 1

Create hibernate project

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

Project structure


OneToOneXMLProjStructure

Step 2

Update pom.xml with Hibernate and Mysql dependencies

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<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>OneToOneXML</groupId>
  <artifactId>OneToOneXML</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
 
  <name>OneToOneXML</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>
<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>OneToOneXML</groupId>
  <artifactId>OneToOneXML</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>OneToOneXML</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.kb.model;
 
public class Applicant {
    private int applicantId;
    private String name;
    private int age;
    private String city;
    private Passport passport;
    
    public int getApplicantId() {
        return applicantId;
    }
    public void setApplicantId(int applicantId) {
        this.applicantId = applicantId;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Passport getPassport() {
        return passport;
    }
    public void setPassport(Passport passport) {
        this.passport = passport;
    }
}
package com.kb.model;

public class Applicant {
	private int applicantId;
	private String name;
	private int age;
	private String city;
	private Passport passport;
	
	public int getApplicantId() {
		return applicantId;
	}
	public void setApplicantId(int applicantId) {
		this.applicantId = applicantId;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Passport getPassport() {
		return passport;
	}
	public void setPassport(Passport passport) {
		this.passport = passport;
	}
}


Applicant class has a reference of Passport class to maintain One to One relation.

Step 4

Create Passport class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.kb.model;
 
import java.util.Date;
 
public class Passport {
    private int passportId;
    private String passportNumber;
    private Date issuedDate;
    private Date expiryDate;
    private Applicant applicant;
    
    public int getPassportId() {
        return passportId;
    }
    public void setPassportId(int passportId) {
        this.passportId = passportId;
    }
    public String getPassportNumber() {
        return passportNumber;
    }
    public void setPassportNumber(String passportNumber) {
        this.passportNumber = passportNumber;
    }
    public Date getIssuedDate() {
        return issuedDate;
    }
    public void setIssuedDate(Date issuedDate) {
        this.issuedDate = issuedDate;
    }
    public Date getExpiryDate() {
        return expiryDate;
    }
    public void setExpiryDate(Date expiryDate) {
        this.expiryDate = expiryDate;
    }
    public Applicant getApplicant() {
        return applicant;
    }
    public void setApplicant(Applicant applicant) {
        this.applicant = applicant;
    }
}
package com.kb.model;

import java.util.Date;

public class Passport {
	private int passportId;
	private String passportNumber;
	private Date issuedDate;
	private Date expiryDate;
	private Applicant applicant;
	
	public int getPassportId() {
		return passportId;
	}
	public void setPassportId(int passportId) {
		this.passportId = passportId;
	}
	public String getPassportNumber() {
		return passportNumber;
	}
	public void setPassportNumber(String passportNumber) {
		this.passportNumber = passportNumber;
	}
	public Date getIssuedDate() {
		return issuedDate;
	}
	public void setIssuedDate(Date issuedDate) {
		this.issuedDate = issuedDate;
	}
	public Date getExpiryDate() {
		return expiryDate;
	}
	public void setExpiryDate(Date expiryDate) {
		this.expiryDate = expiryDate;
	}
	public Applicant getApplicant() {
		return applicant;
	}
	public void setApplicant(Applicant applicant) {
		this.applicant = applicant;
	}
}


Passport class has a reference of Applicant class to maintain One to One relation.

Step 5

Create applicant.hbm.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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="name" column="Name"></property>
        <property name="age" type="int" column="Age"></property>
        <property name="city" column="City"></property>
 
        <one-to-one name="passport" class="Passport" cascade="save-update"></one-to-one>
    </class>
</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="name" column="Name"></property>
		<property name="age" type="int" column="Age"></property>
		<property name="city" column="City"></property>

		<one-to-one name="passport" class="Passport" cascade="save-update"></one-to-one>
	</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 one mapping with Passport entity using “one-to-one” tag.

We have also provided cascade attribute value as “save-update” which means whenever we save or update Applicant record it will also save or update the Passport record automatically.

Step 6

Create passport.hbm.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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="Passport" table="Passport">
    
    <id name="passportId" type="int">
            <column name="Passport_Id" />
            <generator class="foreign">
                <param name="property">applicant</param>
            </generator>
        </id>
        <one-to-one name="applicant" class="Applicant"
            constrained="true"></one-to-one>
        
        <property name="passportNumber" column="Passport_Number"/>
        <property name="issuedDate" type="date" column="Issued_Date"/>
        <property name="expiryDate" type="date" column="Expiry_Date"/>
    </class>
</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="Passport" table="Passport">
	
	<id name="passportId" type="int">
			<column name="Passport_Id" />
			<generator class="foreign">
				<param name="property">applicant</param>
			</generator>
		</id>
		<one-to-one name="applicant" class="Applicant"
			constrained="true"></one-to-one>
		
        <property name="passportNumber" column="Passport_Number"/>
        <property name="issuedDate" type="date" column="Issued_Date"/>
        <property name="expiryDate" type="date" column="Expiry_Date"/>
	</class>
</hibernate-mapping>  


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

We have specified Primary key as passportId and generator class as “foreign”.

Generator class “foreign” indicates that Primary key of Passport table will be coming from Applicant table and we have to use the property name as same as relation name which is “applicant”.

We have defined one to one mapping with Applicant entity using “one-to-one” tag.

We have also provided “constrained” as true which specifies that a foreign key constraint on the primary key of the mapped table and references the table of the associated class.

In other words constrained=true ensures that Applicant must exist for the passport record.

Step 7

Create hibernate.cfg.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?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/passport.hbm.xml"/> 
   </session-factory>
 
</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/passport.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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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();
    }
 
}
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.kb.db;
 
import java.util.Calendar;
import java.util.Date;
 
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
 
import com.kb.model.Applicant;
import com.kb.model.Passport;
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.setName("John");
        applicant.setAge(28);
        applicant.setCity("Newyork");
 
        //Create Passport Model data
        Passport passport = new Passport();
        passport.setPassportNumber("ABCDE1111Z");
        passport.setIssuedDate(new Date());
        Calendar date = Calendar.getInstance();
        date.setTime(new Date());
        date.add(Calendar.YEAR, 10);
        passport.setExpiryDate(date.getTime());
 
        applicant.setPassport(passport);
        passport.setApplicant(applicant);
        session.persist(applicant);
 
        // Commit the transaction and close the session
        t.commit();
        session.close();
        System.out.println("successfully persisted Applicant details");
    }
 
}
package com.kb.db;

import java.util.Calendar;
import java.util.Date;

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

import com.kb.model.Applicant;
import com.kb.model.Passport;
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.setName("John");
		applicant.setAge(28);
		applicant.setCity("Newyork");

		//Create Passport Model data
		Passport passport = new Passport();
		passport.setPassportNumber("ABCDE1111Z");
		passport.setIssuedDate(new Date());
		Calendar date = Calendar.getInstance();
		date.setTime(new Date());
		date.add(Calendar.YEAR, 10);
		passport.setExpiryDate(date.getTime());

		applicant.setPassport(passport);
		passport.setApplicant(applicant);
		session.persist(applicant);

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

}


We have created one Applicant and associated a Passport to that Applicant.

We are persisting only Applicant but both Applicant and Passport will be saved into DB.

It’s because we have given cascade=save-update in applicant.hbm.xml file.

Step 10

Run the above class to check the output

Hibernate: 
    
    create table Applicant (

       Applicant_Id integer not null,

        Name varchar(255),

        Age integer,

        City varchar(255),

        primary key (Applicant_Id)
    )


Hibernate: 
    
    create table Passport (

       Passport_Id integer not null,

        Passport_Number varchar(255),

        Issued_Date date,

        Expiry_Date date,

        primary key (Passport_Id)
    )


Hibernate: 
    
    alter table Passport 

       add constraint FKh6nj623boddru6w09ftabw82g 

       foreign key (Passport_Id) 

       references Applicant (Applicant_Id)


Hibernate: 

    select
        max(Applicant_Id) 

    from
        Applicant


Hibernate: 

    insert 

    into
        Applicant
        (Name, Age, City, Applicant_Id) 

    values
        (?, ?, ?, ?)


Hibernate: 

    insert 

    into
        Passport
        (Passport_Number, Issued_Date, Expiry_Date, Passport_Id) 

    values
        (?, ?, ?, ?)

successfully persisted Applicant details


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

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

2 insert statements are executed (one for Applicant and one for Passport).

Check Table in MYSQL console

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

Use javainsimpleway;

Select * from Applicant;

Select * from Passport;

OneToOneXMLOutput

We can see that same primary key is shared between Applicant and Passport table.

Download this project OneToOneXML.zip

About the Author

Karibasappa G C (KB)
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