Hibernate one-to-one mapping using annotations

If you are working on any hibernate project or you are planning to work on any in future, then you can easily understand the one-to-one relationships between several entities in your application. In this post, i will discuss variations of one-to-one mappings supported in hibernate.

Download source code

Sections in this post:
Various supported techniques
Using foreign key association
Using a common join table
Using shared primary key

For this article, I am extending the example written for hello world example. We have two entities here: Employee and Account.

Various supported techniques

In hibernate there are 3 ways to create one-to-one relationships between two entities. Either way you have to use @OneToOne annotation. First technique is most widely used and uses a foreign key column in one to table. Second technique uses a rather known solution of having a third table to store mapping between first two tables. Third technique is something new which uses a common primary key value in both the tables.

Lets see them in action one by one:

Using foreign key association

In this association, a foreign key column is created in owner entity. For example, if we make EmployeeEntity owner, then a extra column “ACCOUNT_ID” will be created in Employee table. This column will store the foreign key for Account table.

Table structure will be like this:

foreign key association one to one

To make such association, refer the account entity in EmployeeEntity class as follow:

private AccountEntity account;

The join column is declared with the @JoinColumn annotation which looks like the @Column annotation. It has one more parameters named referencedColumnName. This parameter declares the column in the targeted entity that will be used to the join.

If no @JoinColumn is declared on the owner side, the defaults apply. A join column(s) will be created in the owner table and its name will be the concatenation of the name of the relationship in the owner side, _ (underscore), and the name of the primary key column(s) in the owned side.

In a bidirectional relationship, one of the sides (and only one) has to be the owner: the owner is responsible for the association column(s) update. To declare a side as not responsible for the relationship, the attribute mappedBy is used. mappedBy refers to the property name of the association on the owner side.

private EmployeeEntity employee;

Above “mappedBy” attribute declares that it is dependent on owner entity for mapping.

Lets test above mappings in running code:

public class TestForeignKeyAssociation {

	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();

		AccountEntity account = new AccountEntity();

		// Add new Employee object
		EmployeeEntity emp = new EmployeeEntity();

		// Save Account
		// Save Employee


Running above code creates desired schema in database and run these SQL queries.

Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)
Hibernate: insert into Employee (ACCOUNT_ID, EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?, ?)

You can verify the data and mappings in both tables when you run above program.. :-)

Using a common join table

This approach is not new to all of us. Lets start with targeted DB structure in this technique.

join table one to one mapping

In this technique, main annotation to be used is @JoinTable. This annotation is used to define the new table name (mandatory) and foreign keys from both of the tables. Lets see how it is used:

@OneToOne(cascade = CascadeType.ALL)
@JoinTable(name="EMPLOYEE_ACCCOUNT", joinColumns = @JoinColumn(name="EMPLOYEE_ID"),
inverseJoinColumns = @JoinColumn(name="ACCOUNT_ID"))
private AccountEntity account;

@JoinTable annotation is used in EmployeeEntity class. It declares that a new table EMPLOYEE_ACCOUNT will be created with two columns EMPLOYEE_ID (primary key of EMPLOYEE table) and ACCOUNT_ID (primary key of ACCOUNT table).

Testing above entities generates following SQL queries in log files:

Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)
Hibernate: insert into Employee (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)
Hibernate: insert into EMPLOYEE_ACCCOUNT (ACCOUNT_ID, EMPLOYEE_ID) values (?, ?)

Using shared primary key

In this technique, hibernate will ensure that it will use a common primary key value in both the tables. This way primary key of EmployeeEntity can safely be assumed the primary key of AccountEntity also.

Table structure will be like this:

shared primary key one to one

In this approach, @PrimaryKeyJoinColumn is the main annotation to be used.Let see how to use it.

@OneToOne(cascade = CascadeType.ALL)
private AccountEntity account;

In AccountEntity side, it will remain dependent on owner entity for the mapping.

@OneToOne(mappedBy="account", cascade=CascadeType.ALL)
private EmployeeEntity employee;

Testing above entities generates following SQL queries in log files:

Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)
Hibernate: insert into Employee (ACCOUNT_ID, EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?, ?)

So, we have seen all 3 types of one to one mappings supported in hibernate. I will suggest you to download the source code and play with it.

Happy Learning !!

Download source code

15 thoughts on “Hibernate one-to-one mapping using annotations”
  1. i need a help,
    we have a list as field to store it in data base,
    for this we have to use hibernate annotations mapping class(no hibernate mapping file should be used), pojo class object contains some fields as List, those fileds will be inserted into db as string by mapping class. if possible for you, give an example

  2. HI Lokesh,
    Good after noon,

    Currently i am working with hibernate 3. i have been trying to develop a simple hibernate project with one to many relationship.every thing is fine but i am getting error like. i have placed cfg.xml file under src folder.is correct. why i am getting error. please suggest me. as soon as…..

    log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
    log4j:WARN Please initialize the log4j system properly.
    Initial SessionFactory creation failed.org.hibernate.HibernateException: could not find file: hibernate.cgf.xml
    Exception in thread “main” java.lang.ExceptionInInitializerError
    at com.hib.pro.HibernateUtil.buildSessionFactory(HibernateUtil.java:23)
    at com.hib.pro.HibernateUtil.(HibernateUtil.java:11)
    at com.hib.pro.TestForeignKeyAssociation.main(TestForeignKeyAssociation.java:19)
    Caused by: org.hibernate.HibernateException: could not find file: hibernate.cgf.xml
    at org.hibernate.cfg.Configuration.configure(Configuration.java:1462)
    at com.hib.pro.HibernateUtil.buildSessionFactory(HibernateUtil.java:18)
    … 2 more
    Caused by: java.io.FileNotFoundException: hibernate.cgf.xml (The system cannot find the file specified)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.(FileInputStream.java:106)
    at org.hibernate.cfg.Configuration.configure(Configuration.java:1459)
    … 3 more

    1. Usually src folders have filters which cause to generate only .class files in target folder or classes folder. Copy the file in resources folder. The important thing is that file should be present in target folder (war file).

  3. Hi Lokesh,

    Good Work. But I see a flaw in the DB design of your “Using foreign key association”. In the Employee Table one can have one account shared by the multiple employees which does not make it one to one but many to one. For that you need to put Unique constraint on Account Id column in Employee Table. Please clarify.

    1. Abhi, you are right. It should be implemented this way. But, also that’s not core concept for this tutorial. Mixing concepts in single post, sometimes push the core concept in back seat. Which i did not wanted to do, otherwise in any code review session, I can myself blew this code. [:-)]

  4. Thank you sir, My name is A Aravind ,i had completed my B.Tech with an aggregate of 70%,belongs to ECE stream. Now i need to learn JAVA very effectively,i need to get placed in Java only in reputed companies. So can you please upload Core Java tutorials,JSP,SERVLETS,Struts and Hibernates. Because i am having knowledge on only Core Java,now i want to learn Struts,Hiberbates,EJB from you.

    Thanking You, A.Aravind

Note:- In comment box, please put your code inside [java] ... [/java] OR [xml] ... [/xml] tags otherwise it may not appear as intended.

Leave a Reply

Your email address will not be published. Required fields are marked *