This Hibernate tutorial demonstrates how to use JPA annotations in order to implement a unidirectional one-to-one association on a foreign key. This is similar to the tutorial Hibernate One-to-One With Foreign Key XML Mapping Example but using annotations instead of XML descriptor. The following diagram recalls the one-to-one entity relationship:

One-to-One table relationship diagram

A book belongs to only one author, and we can only know the author from the book, not vice-versa. Thus the association is called unidirectional (one-way).

We are going to develop a sample Hibernate application using the following technologies/software programs:

Note that we use the latest stuffs to date, you can use little bit lower or higher versions. Now, let’s following the steps below:

Table of content:

  1. Creating Database and Tables
  2. Creating Eclipse Project
  3. Coding Model Classes with Annotations
  4. Writing Hibernate Configuration File
  5. Writing a Test Program

 

1. Creating Database and Tables

Execute the following MySQL script to create the database booksdb with two tables author and book:

create database booksdb;
use booksdb;

CREATE TABLE `author` (
  `author_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `email` varchar(45) NOT NULL,
  PRIMARY KEY (`author_id`)
);

CREATE TABLE `book` (
  `book_id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(128) NOT NULL,
  `description` varchar(512) NOT NULL,
  `published` date NOT NULL,
  `author_id` int(11) NOT NULL,
  PRIMARY KEY (`book_id`),
  KEY `author_fk` (`author_id`),
  CONSTRAINT `author_fk` FOREIGN KEY (`author_id`) REFERENCES `author` (`author_id`)
);

 The database structure looks like this:

booksdb database structure in MySQL Workbench

 

2. Creating Eclipse Project

Create a Maven project in Eclipse with the following structure:

Hibernate one-to-one annotations project structure

The project consists of the following files:

  • Model classes: Author.java and Book.java
  • Hibernate XML configuration file: hibernate.cfg.xml
  • Test program: BooksManager.java
  • Maven project: pom.xml

Here’s content of the pom.xml file:

<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>HibernateOne2OneAnnnotationsExample</groupId>
  <artifactId>HibernateOne2OneAnnnotationsExample</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <description>Example of a Hibernate one-to-one mapping with 
  	foreign key using annotations</description>
  <dependencies>
  	<dependency>
  		<groupId>org.hibernate</groupId>
  		<artifactId>hibernate-core</artifactId>
  		<version>4.2.7.SP1</version>
  	</dependency>
  	<dependency>
  		<groupId>mysql</groupId>
  		<artifactId>mysql-connector-java</artifactId>
  		<version>5.1.26</version>
  	</dependency>
  </dependencies>
</project>

Here, we specify two main dependencies: hibernate-core and mysql-connector-java. Maven will resolve other related dependencies automatically.

 

3. Coding Model Classes with Annotations

The followings are code of the two model classes: Author.java and Book.java.

File net\codejava\hibernate\Author.java:

package net.codejava.hibernate;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "AUTHOR")
public class Author {
	private long id;
	private String name;
	private String email;
	
	public Author() {
	}
			
	public Author(String name, String email) {
		this.name = name;
		this.email = email;
	}

	@Id
	@Column(name = "AUTHOR_ID")
	@GeneratedValue
	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}	
}

 

File net\codejava\hibernate\Book.java:

package net.codejava.hibernate;

import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name = "BOOK")
public class Book {
	private long id;
	private String title;
	private String description;
	private Date publishedDate;
	
	private Author author;

	public Book() {
	}

	@Id
	@Column(name = "BOOK_ID")
	@GeneratedValue
	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	@Temporal(TemporalType.DATE)
	@Column(name = "PUBLISHED")
	public Date getPublishedDate() {
		return publishedDate;
	}

	public void setPublishedDate(Date publishedDate) {
		this.publishedDate = publishedDate;
	}

	@OneToOne(cascade = CascadeType.ALL)
	@JoinColumn(name = "AUTHOR_ID")
	public Author getAuthor() {
		return author;
	}

	public void setAuthor(Author author) {
		this.author = author;
	}
}

 As you notice, we use the following JPA annotations:

  • @Entity: is required for every model class.
  • @Table: maps the class with the corresponding database table. If omitted, Hibernate will use the class name.
  • @Column: maps the field with the corresponding table column. If omitted, Hibernate will infer the column name and type based on signatures of the getter/setter.
  • @Id and @GeneratedValue: are used in conjunction for a field that maps to the primary key. The values for this field are auto generated.
  • @Temporal: must be used with a java.util.Date field to specify the actual SQL type of the column.
  • @OneToOne and @JoinColumn: are used together to specify a one-to-one association and the join column.

Using annotations is usually preferred over XML descriptor because it’s simple and straightforward in the code.

 

4. Writing Hibernate Configuration File

Write XML configuration for database settings and mapping classes in the hibernate.cfg.xml file as follows:

<?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 settings -->
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="connection.url">jdbc:mysql://localhost:3306/booksdb</property>
    <property name="connection.username">root</property>
    <property name="connection.password">P@ssw0rd</property>
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="show_sql">true</property>
    
    <mapping class="net.codejava.hibernate.Book"/>
    <mapping class="net.codejava.hibernate.Author"/>
      
  </session-factory>
</hibernate-configuration>

 

5. Writing a Test Program

Write code for the test program (BooksManager.java) as follows:

package net.codejava.hibernate;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

/**
 * This program demonstrates using Hibernate framework to manage
 * a one-to-one mapping with foreign key using annotations. 
 * @author www.codejava.net
 *
 */
public class BooksManager {

	public static void main(String[] args) {
		
		// loads configuration and mappings
		Configuration configuration = new Configuration().configure();
		ServiceRegistryBuilder registry = new ServiceRegistryBuilder();
		registry.applySettings(configuration.getProperties());
		ServiceRegistry serviceRegistry = registry.buildServiceRegistry();
		
		// builds a session factory from the service registry
		SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
		
		// obtains the session
		Session session = sessionFactory.openSession();
		session.beginTransaction();
		
		// creates a Book entity
		Book newBook = new Book();
		newBook.setTitle("Hibernate Made Easy");
		newBook.setDescription("Simplified Data Persistence with Hibernate and JPA");
		newBook.setPublishedDate(new Date());
		
		newBook.setAuthor(new Author("Cameron Wallace McKenzie", "Cameron@gmail.com"));
		
		// persists the book entity
		Long bookId = (Long) session.save(newBook);
		
		// gets the book entity back
		Book book = (Book) session.get(Book.class, bookId);
		System.out.println("Book's Title: " + book.getTitle());
		System.out.println("Book's Description: " + book.getTitle());
		
		Author author = book.getAuthor();
		System.out.println("Author's Name: " + author.getName());
		System.out.println("Author's Email: " + author.getEmail());
		
		session.getTransaction().commit();
		session.close();		
	}
}

Output of the program:

Hibernate: insert into AUTHOR (email, name) values (?, ?)
Hibernate: insert into BOOK (AUTHOR_ID, description, PUBLISHED, title) values (?, ?, ?, ?)
Book's Title: Hibernate Made Easy
Book's Description: Hibernate Made Easy
Author's Name: Cameron Wallace McKenzie

Result in the Book table:

records in book table

Result in the Author table:

records in author table

You can download the sample project attached below, or check the code on GitHub here.

 

Related Hibernate One-to-One Tutorials:

 

Other Hibernate Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Attachments:
Download this file (HibernateOne2OneAnnnotationsExample.zip)HibernateOne2OneAnnnotationsExample.zip[Eclipse-Maven project]15 kB

Add comment

   


Comments 

#11asdf_username2023-01-28 18:08
This is not xml mapping??? This is annotations
Quote
#10Raghavendra2017-06-09 08:11
How to save for the second book by the same Author??
Quote
#9baali boudjemaa2017-03-18 13:10
hi thank's i get this error
Caused by: org.dom4j.DocumentException: Error on line 1 of document : Content is not allowed in prolog. Nested exception: Content is not allowed in prolog.
Quote
#8shva2016-11-30 06:56
hi
this is the example
Quote
#7vaseem2016-11-28 00:25
onetoone mapping using hibernate
Quote