- Details
- Written by Nam Ha Minh
- Last Updated on 12 December 2023   |   Print Email
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:
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:- Creating Database and Tables
- Creating Eclipse Project
- Coding Model Classes with Annotations
- Writing Hibernate Configuration File
- Writing a Test Program
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:
Create a Maven project in Eclipse with the following 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.
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.
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>
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:
Result in the
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:
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on
Facebook and watch
his Java videos you YouTube.