Table of content:

    1. What’s in this tutorial?
    2. When to use annotations?
    3. Quick reference on annotations used
    4. Tools needed
    5. Project Structure
    6. Setup Database Configuration
    7. Create annotated model classes
    8. Create Database
    9. Writing Test Program
 

1. What’s in this tutorial?

We’ll setup a sample Hibernate application here which demonstrates the usage of annotations.

    • Create a database connection configuration using XML
    • Create model classes Person and Address and establish a many-to-many relationship between them and map them with database using annotations
    • Obtain connection using Configuration object and build a SessionFactory object
    • Obtain Session objects to perform a save operation using Hibernate APIs

2. When to use annotations?

Use annotations to provide metadata configuration along with the Java code. That way the code is easy to understand. Annotations are less powerful than XML configuration. XML also gives you the ability to change the configuration without building the project. So use annotations only for table and column mappings, not for frequently changing stuff like database connection and other properties. Annotations are preconfigured with sensible default values, which reduce the amount of coding required, e.g. class name defaults to table name and field names defaults to column names.

 

3. Quick reference on Hibernate annotations used

Annotation

Modifier

Description

@Entity

 

Marks a class as a Hibernate Entity (Mapped class)

@Table

Name

Maps this class with a database table specified by name modifier. If name is not supplied it maps the class with a table having same name as the class

@Id

 

Marks this class field as a primary key column

@GeneratedValue

 

Instructs database to generate a value for this field automatically

@Column

Name

Maps this field with table column specified by name and uses the field name if name modifier is absent

 

 

@ManyToMany

Cascade

Marks this field as the owning side of the many-to-many relationship and cascade modifier specifies which operations should cascade to the inverse side of relationship

mappedBy

This modifier holds the field which specifies the inverse side of the relationship

 

 

 

 

@JoinTable

Name

For holding this many-to-many relationship, maps this field with an intermediary database join table specified by name modifier

joinColumns

Identifies the owning side of columns which are necessary to identify a unique owning object

inverseJoinColumns

Identifies the inverse (target) side of columns which are necessary to identify a unique target object

@JoinColumn

Name

Maps a join column specified by the name identifier to the relationship table specified by @JoinTable

 

4. Tools needed in this tutorial

5. Project Structure

ProjectStructure

6. Setup Database Configuration

Create hibernate.cfg.xml file as shown in above figure and configure the database connection and mapping classes. Here is the XML configuration: 

<?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>
		<property name="hibernate.show_sql">false</property>
		<property name="hibernate.format_sql">true</property>
		<property name="use_sql_comments">false</property>

		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernateTutorial</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">secret</property>

		<!-- add classes to map from here -->
		<mapping class="net.codejava.hibernate.model.Person" />
		<mapping class="net.codejava.hibernate.model.Address" />
	</session-factory>
</hibernate-configuration>


Here we instructed Hibernate to connect to a MySQL database named hibernateTutorial. As you can see, we supplied database URL, username and password for the connection. We also instructed Hibernate to use MySQLDialect i.e. Hibernate will optimize the generated SQL statements for MySQL. We also added couple of entities called Person and Address which we’ll configure later. This configuration will be used to create a Hibernate SessionFactory object.

 

7. Create annotated model classes

Create model classes Person.java and map it to the database using annotations as follows: 

package net.codejava.hibernate.model;

import java.util.HashSet;
import java.util.Set;

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.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name = "person")
public class Person {

	long id;
	String firstName;
	String lastName;
	Set<Address> addresses;

	public Person() {

	}

	public Person(String firstName, String lastName) {
		this.firstName = firstName;
		this.lastName = lastName;
		this.addresses = new HashSet<Address>();
	}

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

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

	@Column
	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	@Column
	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	@ManyToMany(cascade = { CascadeType.ALL })
	@JoinTable(name = "person_address", joinColumns = { @JoinColumn(name = "person_id") }, inverseJoinColumns = { @JoinColumn(name = "address_id") })
	public Set<Address> getAddresses() {
		return addresses;
	}

	public void setAddresses(Set<Address> addresses) {
		this.addresses = addresses;
	}

}
Create model classes Address.java and map it to the database using annotations as follows: 

package net.codejava.hibernate.model;

import java.util.Set;

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

@Entity
@Table(name = "address")
public class Address {

	long id;
	String buildingName;
	String town;
	String postCode;
	Set<Person> persons;

	public Address() {

	}

	public Address(String buildingName, String town, String postCode) {
		this.buildingName = buildingName;
		this.town = town;
		this.postCode = postCode;
	}

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

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

	@Column
	public String getBuildingName() {
		return buildingName;
	}

	public void setBuildingName(String buildingName) {
		this.buildingName = buildingName;
	}

	@Column
	public String getTown() {
		return town;
	}

	public void setTown(String town) {
		this.town = town;
	}

	@Column
	public String getPostCode() {
		return postCode;
	}

	public void setPostCode(String postCode) {
		this.postCode = postCode;
	}

	@ManyToMany(mappedBy = "addresses")
	public Set<Person> getPersons() {
		return persons;
	}

	public void setPersons(Set<Person> persons) {
		this.persons = persons;
	}

}
 

8. Create Database

Now go to any MySQL query tool (Preferably SQLYog)

Create a database called hibernatetutorial with utf8 encoding: 

CREATE DATABASE hibernatetutorial CHARACTER SET = utf8 COLLATE = utf8_bin;
 

Create person, address and person_address tables as follows:

create table address (
        address_id bigint not null auto_increment,
        buildingName varchar(255),
        postCode varchar(255),
        town varchar(255),
        primary key (address_id)
    );

create table person (
        person_id bigint not null auto_increment,
        firstName varchar(255),
        lastName varchar(255),
        primary key (person_id)
    );

create table person_address (
        person_id bigint not null,
        address_id bigint not null,
        primary key (person_id, address_id)
);
 

Here’s the table relationship diagram:

table relationship diagram

As you can see, there is a one-to-many relationship between person and person_address, one-to-many relationship between address and person_address and as a result of that, many-to-many relationship between person and address tables.

 

9. Writing Hibernate Test Program

Create a HibernateUtil class to read XML database configuration we did earlier and create a Configuration object to obtain a SessionFactory object. Please make sure that hibernate.cfg.xml file is on the classpath. Following is code of the HibernateUtil.java class: 

package net.codejava.hibernate.util;

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

public class HibernateUtil {

	private static final SessionFactory sessionFactory = buildSessionFactory();

	private static SessionFactory buildSessionFactory() {
		try {
			// Create the SessionFactory from hibernate.cfg.xml
			Configuration configuration = new Configuration();
			configuration.configure("hibernate.cfg.xml");
			ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
					.applySettings(configuration.getProperties())
					.buildServiceRegistry();
			return configuration.buildSessionFactory(serviceRegistry);
		} catch (Throwable ex) {
			System.err.println("Initial SessionFactory creation failed." + ex);
			throw new ExceptionInInitializerError(ex);
		}
	}

	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}
}
Ideally, it’s a good practice to create one SessionFactory object per data store at global application level scope. Hence here we are creating just one static SessionFactory object when the class is first loaded and then we access the same via getSessionFactory() static method. This is the safest implementation of a singleton object.

Now let’s create a PersonManager class which creates 2 person and 3 address objects and persists them to the database. Note that all the addresses have been persisted using Hibernate cascade functionality. Here is code of the PersonManager.java class: 

package net.codejava.hibernate.manager;

import net.codejava.hibernate.model.Address;
import net.codejava.hibernate.model.Person;
import net.codejava.hibernate.util.HibernateUtil;

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

public class PersonManager {

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

		Person steve = new Person("Steve", "Jobs");
		Person donald = new Person("Donald", "Trump");

		Address valley = new Address("Steve P Jobs", "San Francisco", "11111");
		Address newyork = new Address("Trump Tower", "New York", "22222");
		Address chicago = new Address("Trump Tower", "Chicago", "33333");

		steve.getAddresses().add(valley);
		donald.getAddresses().add(newyork);
		donald.getAddresses().add(chicago);

		System.out.println("Creating Person: " + steve.getFirstName());
		session.persist(steve);
		System.out.println("Creating Person: " + donald.getFirstName());
		session.persist(donald);

		session.getTransaction().commit();
		session.close();
	}

}
 

Just right click in the editor window and run the project as Java application. You should see following output in the console… 

Creating Person: Steve
Creating Person: Donald
Here’s the final database presentation you should see:

PersonTable

Person table

 

AddressTable

Address table

 

Person AddressTable

Person_Address table

Above you can see that in person table, persons Steve and Donald have been saved with auto generated ids 1 and 2 respectively. In address table, addresses San Francisco, Chicago and New York have been saved with auto generated ids 1, 2 and 3 respectively. Also in person_address table person_id 1 is associated with address_id 1 and person_id 2 is associated with address_ids 2 and 3 respectively.

This tutorial shows how easily you can configure session factory connection details using XML and entities using annotation configuration respectively in Hibernate and access the database. By using XML, database connection properties can be easily changed without changing the Java source files which is an added advantage. By using annotations, Java entity classes are more expressive and you don’t have to refer to another XML file for figuring out the Hibernate-Database mapping.

Above shown code snippets can be downloaded as a full Eclipse project along with the accompanying jar files from the attachment section.

 

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 (HibernateAnnotationTutorial.zip)HibernateAnnotationTutorial.zip[ ]6267 kB

Add comment

   


Comments 

#10Nam2021-01-28 03:00
Hi DC,
This is exactly what you need: codejava.net/.../...
Quote
#9DC2021-01-27 19:37
Hello,
I find this tutorial very helpful, thank very much indeed.
I wanted to know if you have a tutorial explaining how to install Hibernate-JPA annotations in Eclipse using JDK 8?
Thank you.
DC
Quote
#8ingrid2018-03-02 13:29
please send the upgrade version
Quote
#7Jawhar Mbarek2017-09-21 05:24
Good Tutorial for hibernate with annotations, one adjustement in HibernateUtil class,
It works for me only by applying configuration property settings to ServiceRegistryBuilder.
like here:
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.buildServiceRegistry();
Quote
#6Nam2015-02-09 22:08
Hi Stephen Nutbrown,

I'm very happy that you found this tutorial helpful. Also your link for dependencies is great. Thank you so much!
Quote