Hibernate One To One Annotation Mapping Tutorial

Let us understand how One-to-one relationship is implemented in Hibernate using Annotations. For this we
will use our previous article One-to-one mapping in Hibernate using XML mapping and enhance it to support Annotations.

Tools and Technologies used in this article:

  1. Java JDK 1.5 above
  2. MySQL 5 above
  3. Eclipse 3.2 above
  4. Hibernate 3 above
  5. Maven 3 above

1. Database with One-to-one relationship tables

We will use the same tables we created in our previous article for this example. Following is the SQL code:

/* EMPLOYEE table */ CREATE TABLE `employee` ( `employee_id` BIGINT(10) NOT NULL AUTO_INCREMENT, `firstname` VARCHAR(50) NULL DEFAULT NULL, `lastname` VARCHAR(50) NULL DEFAULT NULL, `birth_date` DATE NOT NULL, `cell_phone` VARCHAR(15) NOT NULL, PRIMARY KEY (`employee_id`) ) COLLATE='latin1_swedish_ci' ENGINE=InnoDB ROW_FORMAT=DEFAULT AUTO_INCREMENT=216 /* EMPLOYEEDETAIL table */ CREATE TABLE `employeedetail` ( `employee_id` BIGINT(20) NOT NULL AUTO_INCREMENT, `street` VARCHAR(50) NULL DEFAULT NULL, `city` VARCHAR(50) NULL DEFAULT NULL, `state` VARCHAR(50) NULL DEFAULT NULL, `country` VARCHAR(50) NULL DEFAULT NULL, PRIMARY KEY (`employee_id`), CONSTRAINT `FKEMPL` FOREIGN KEY (`employee_id`) REFERENCES `employee` (`employee_id`) ) COLLATE='latin1_swedish_ci' ENGINE=InnoDB ROW_FORMAT=DEFAULT AUTO_INCREMENT=216
Code language: SQL (Structured Query Language) (sql)

So we have created two tables “EMPLOYEE” and “EMPLOYEEDETAILS” which have One-to-one relational mapping. These two tables are mapped by primary key Employee_ID.

2. Model class to Entity class

We had define two model classes Employee.java and EmployeeDetail.java in our previous example. These classes will be converted to Entity classes and we will add Annotations to it.

File: /src/main/java/net/viralpatel/hibernate/Employee.java

package net.viralpatel.hibernate; import java.sql.Date; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.Table; @Entity @Table(name="EMPLOYEE") public class Employee { @Id @GeneratedValue @Column(name="employee_id") private Long employeeId; @Column(name="firstname") private String firstname; @Column(name="lastname") private String lastname; @Column(name="birth_date") private Date birthDate; @Column(name="cell_phone") private String cellphone; @OneToOne(mappedBy="employee", cascade=CascadeType.ALL) private EmployeeDetail employeeDetail; public Employee() { } public Employee(String firstname, String lastname, Date birthdate, String phone) { this.firstname = firstname; this.lastname = lastname; this.birthDate = birthdate; this.cellphone = phone; } // Getter and Setter methods }
Code language: Java (java)

File: /src/main/java/net/viralpatel/hibernate/EmployeeDetail.java

package net.viralpatel.hibernate; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Parameter; @Entity @Table(name="EMPLOYEEDETAIL") public class EmployeeDetail { @Id @Column(name="employee_id", unique=true, nullable=false) @GeneratedValue(generator="gen") @GenericGenerator(name="gen", strategy="foreign", parameters=@Parameter(name="property", value="employee")) private Long employeeId; @Column(name="street") private String street; @Column(name="city") private String city; @Column(name="state") private String state; @Column(name="country") private String country; @OneToOne @PrimaryKeyJoinColumn private Employee employee; public EmployeeDetail() { } public EmployeeDetail(String street, String city, String state, String country) { this.street = street; this.city = city; this.state = state; this.country = country; } // Getter and Setter methods }
Code language: Java (java)

Note that in EmployeeDetail class we have used @GenericGenerator to specify primary key. This will ensure that the primary key from Employee table is used instead of generating a new one.

3. Remove Hibernate Mapping (hbm) Files

Delete the hibernate mapping files Employee.hbm.xml and EmployeeDetail.hbm.xml as we do not need them anymore. The mapping is now defined in Java class as Annotation.

4. Update Hibernate Configuration

Edit Hibernate configuration file (hibernate.cfg.xml) and add mappings for Employee and EmployeeDetail classes. Following is the final hibernate.cfg.xml file:

<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- Database connection settings --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/tutorial</property> <property name="connection.username">root</property> <property name="connection.password"></property> <property name="connection.pool_size">1</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="current_session_context_class">thread</property> <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">validate</property> <mapping class="net.viralpatel.hibernate.EmployeeDetail"/> <mapping class="net.viralpatel.hibernate.Employee"/> </session-factory> </hibernate-configuration>
Code language: HTML, XML (xml)

5. Update Hibernate Dependency in Maven

Update the Maven pom.xml and define following Hibernate dependency into it:

<?xml version="1.0" encoding="UTF-8"?><project> <modelVersion>4.0.0</modelVersion> <groupId>HibernateCache</groupId> <artifactId>HibernateCache</artifactId> <version>0.0.1-SNAPSHOT</version> <description></description> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>ejb3-persistence</artifactId> <version>1.0.1.GA</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-annotations</artifactId> <version>3.3.1.GA</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.10</version> </dependency> </dependencies> </project>
Code language: HTML, XML (xml)

6. Update Hibernate Utility class

In previous example, the Hibernate Utility class uses Hibernate’s org.hibernate.cfg.Configuration class to generate SessionFactory. For this example we will replace this class with org.hibernate.cfg.AnnotationConfiguration class. Following is the code for HibernateUtil.java class.

File: /src/main/java/net/viralpatel/hibernate/HibernateUtil.java

package net.viralpatel.hibernate; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { // Create the SessionFactory from hibernate.cfg.xml return new AnnotationConfiguration().configure() .buildSessionFactory(); } catch (Throwable ex) { System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } }
Code language: Java (java)

7. Main class to test One-to-one mapping

Execute following Main class to test One-to-one relational mapping using Annotation.

File: /src/main/java/net/viralpatel/hibernate/Main.java

package net.viralpatel.hibernate; import java.sql.Date; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; public class Main { @SuppressWarnings("unchecked") public static void main(String[] args) { System.out.println("Hibernate One-To-One example (Annotation)"); SessionFactory sf = HibernateUtil.getSessionFactory(); Session session = sf.openSession(); session.beginTransaction(); EmployeeDetail employeeDetail = new EmployeeDetail("10th Street", "LA", "San Francisco", "U.S."); Employee employee = new Employee("Nina", "Mayers", new Date(121212), "114-857-965"); employee.setEmployeeDetail(employeeDetail); employeeDetail.setEmployee(employee); session.save(employee); List<Employee> employees = session.createQuery("from Employee").list(); for (Employee employee1 : employees) { System.out.println(employee1.getFirstname() + " , " + employee1.getLastname() + ", " + employee1.getEmployeeDetail().getState()); } session.getTransaction().commit(); session.close(); } }
Code language: Java (java)

8. Review Final Project Structure

The final project structure should looks like following:

Execute Main Class

Execute the Main class and find the below output.

Output:

Hibernate One-To-One example (Annotation) Hibernate: insert into EMPLOYEE (birth_date, cell_phone, firstname, lastname) values (?, ?, ?, ?) Hibernate: insert into EMPLOYEEDETAIL (city, country, state, street, employee_id) values (?, ?, ?, ?, ?) Hibernate: select employee0_.employee_id as employee1_1_, employee0_.birth_date as birth2_1_, employee0_.cell_phone as cell3_1_, employee0_.firstname as firstname1_, employee0_.lastname as lastname1_ from EMPLOYEE employee0_ Nina , Mayers, San Francisco
Code language: SQL (Structured Query Language) (sql)

Download Source Code

Hibernate-One-to-one-tutorial-Annotations.zip (8 kb)

View Comments

  • hi this is guptha
    this tutorial help me a lot
    i wish to know how configure Hibernate 3 above Maven 3 above in eclipse

    please help me

    thank you

  • This is a very, very good tutorial. One of the difficulty is which strategy to use and the relationship, because that all depends on how deep is your existing table model.
    I been using bottom up approach but many time don't know how to map.
    You did an excellent job because it is short and easy to read. You have the database script, model diagram. All is all in one very clear from end to end, programmaticly and visually.

  • Your tutorial is really good. But it would be helpful if you mention which all jars (versions) to be included in the build path

  • in the date place instead of the whole date ( date with time) i want only date .
    i have tried like this...
    [code language="java"]
    @Column(name="transctionDate")
    @Temporal(TemporalType.DATE)
    public Date getTransctionDate() {
    return transctionDate;
    }
    [/code]
    can u pls suggest me?

    • I would suggest to leave hibernate mapping like this only. Fetch whole Date with Time. In your view format the date and print only date part.

  • how to run this example in eclipse ...
    Run on Server or Run Java Application which of them...
    I want to know about the objects that is carried by the page to action and then controller...
    thanks for your sample .. that is good ..
    Thanks anyway ,,,

  • log4j:WARN No appenders could be found for logger (com.opensymphony.xwork2.config.providers.XmlConfigurationProvider).
    log4j:WARN Please initialize the log4j system properly.
    Initial SessionFactory creation failed.java.lang.NullPointerException
    Aug 15, 2012 2:23:02 PM org.apache.catalina.core.StandardWrapperValve invoke
    SEVERE: Servlet.service() for servlet default threw exception
    java.lang.NullPointerException
    at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:135)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1163)
    at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:296)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1319)
    at net.viralpatel.contact.util.HibernateUtil.buildSessionFactory(HibernateUtil.java:14)
    at net.viralpatel.contact.util.HibernateUtil.(HibernateUtil.java:8)
    at net.viralpatel.contact.view.ContactAction.(ContactAction.java:22)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at java.lang.Class.newInstance0(Unknown Source)
    at java.lang.Class.newInstance(Unknown Source)
    at com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:119)
    at com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:150)
    at com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:139)
    at com.opensymphony.xwork2.ObjectFactory.buildAction(ObjectFactory.java:109)
    at com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:288)
    at com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:388)
    at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:187)
    at org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:61)
    at org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
    at com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:47)
    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:478)
    at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:395)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Unknown Source)

    this is my error
    pls suggest me
    thanks

Recent Posts

  • Java

Java URL Encoder/Decoder Example

Java URL Encoder/Decoder Example - In this tutorial we will see how to URL encode/decode…

4 years ago
  • General

How to Show Multiple Examples in OpenAPI Spec

Show Multiple Examples in OpenAPI - OpenAPI (aka Swagger) Specifications has become a defecto standard…

4 years ago
  • General

How to Run Local WordPress using Docker

Local WordPress using Docker - Running a local WordPress development environment is crucial for testing…

4 years ago
  • Java

Create and Validate JWT Token in Java using JJWT

1. JWT Token Overview JSON Web Token (JWT) is an open standard defines a compact…

4 years ago
  • Spring Boot

Spring Boot GraphQL Subscription Realtime API

GraphQL Subscription provides a great way of building real-time API. In this tutorial we will…

5 years ago
  • Spring Boot

Spring Boot DynamoDB Integration Test using Testcontainers

1. Overview Spring Boot Webflux DynamoDB Integration tests - In this tutorial we will see…

5 years ago