Hibernate

Last Updated on: January 21, 2021 am

What is Hibernate?

A framework for persisting / saving Java objects in a database.

Benefits of Hibernate

  • Handles all of the low-level SQL.
  • Minimizes the amount of JDBC code you have to develop.
  • Provides the Object-to-Rational Mapping(ORM).

Object-to-Rational Mapping(ORM)

Mapping between the Java class and database table.

ORM Example

Save Java Object

1
2
3
Student theStudent = new Student("John","john@test.com");
// save it to database
int theId = (Integer)session.save(theStudent);

Hibernate will store the data into the appropriate database - perform SQL insert.

Then Hibernate will return the primary key - theId.

Retrieve Java Object

1
2
// now retrieve from the database using the primary key
Student myStudent = session.get(Student.class, theId);

Query for Java Object

1
2
3
// retrieve all the student objects and store them in a list
Query query = session.create("from Student");
List<Student> students = query.list();

Here, we use the Hibernate Query Language(HQL).

Hibernate and JDBC

  • Hibernate uses JDBC for all database communications.
  • Configure Hibernate to make use of the JDBC driver.

Configurations with Annotations

Developement Process

Add Hibernate Configuration file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<hibernate-configuration>

<session-factory>

<!-- JDBC Database connection settings -->
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hb_student_tracker?useSSL=false&amp;serverTimezone=UTC</property>
<property name="connection.username">hbstudent</property>
<property name="connection.password">hbstudent</property>

<!-- JDBC connection pool settings ... using built-in test pool -->
<property name="connection.pool_size">1</property>

<!-- Select our SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<!-- Echo the SQL to stdout -->
<property name="show_sql">true</property>

<!-- Set the current session context -->
<property name="current_session_context_class">thread</property>

</session-factory>
</hibernate-configuration>

Annotate Java class

Entity Class - Java class that is mapped to a database table / plain old Java Class

  1. Map class to database table

  2. Map fields to database columns

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Entity
@Table(name="student")
public class Student {

@Id
@Column(name = "id")
private int id;

@Column(name = "first_name")
private String firstName;

@Column(name = "last_name")
private String lastName;

@Column(name = "email")
private String email;

Note: Be sure to use import javax.persistence.*.

JPA is a standard specification. Hibernate is an implementation of the JPA specification.

Hibernate implements all of the JPA annotations.

Develop Code to perform database operations

  1. SessionFactory

    • Reads the Hi-config file
    • Creates session object
    • Heavy-weight object
    • Only create once in your app
  2. Session

    • Wraps JDBC connection
    • Main object to save/retrieve objects
    • Short-lived object
    • Retrived from the sessionFactory
1
2
3
4
5
//  Create session factory
SessionFactory factory = new Configuration()
.configure("hibernate.cfg.xml")
.addAnnotatedClass(Student.class)
.buildSessionFactory();

If the name of the config file is not given, Hibernate will automatically look for a file on your class path called hibernate.cfg.xml.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Session session = factory.getCurrentSession();
try{
// use the session objection to save Java Object
System.out.println("Creating a new student object...");
Student tempStudent = new Student("Paul", "Wall", "Paul@test.com");

// Create the student object
session.beginTransaction();

// save the student object
System.out.println("Saving a student...");
session.save(tempStudent);

// commit transaction
session.getTransaction().commit();
System.out.println("Done!");
} finally {
factory.close();
}

Note: There is also a rollback method.

CRUD Features

Create and Save

Stated in the last section.

Primary Keys

1
@GeneratedValue(strategy=GenerationType.IDENTITY)

ID Generation Strategies

  • GenerationType.AUTO
  • GenerationType.IDENTITY - Most commonly used in MySQL, leverage the AUTO_INCREMENT feature of MySQL.
  • GenerationType.SEQUENCE
  • GenerationType.TABLE

Custom Strategy

  • Create a implementation of org.hibernate.id.IdentifierGenerator
  • Override the method: public Serializable generate()

Changing the Starting Index

1
ALTER TABLE hb_student_tracker.student AUTO_INCREMENT=3000;

The index of the object will start from 3000.

1
TRUNCATE hb_student_tracker.student;

Clean up the table and the index will start from 1.

Read Objects

Retrieve from the database using the PK.

1
2
3
4
5
6
7
8
9
10
11
// get a new session and start a transaction
session = factory.getCurrentSession();
session.beginTransaction();

// retrieve a student based on the PK
System.out.println("\nGetting Student with id: "+ tempStudent.getId());
Student myStudent = session.get(Student.class, tempStudent.getId());
System.out.println("Get Completed:" + myStudent);

// commit the transaction
session.getTransaction().commit();

Querying Objects

1
List<Student> theStudents = session.createQuery("from Student s where s.lastName = 'Zhang'").getResultList();

Update Objects

1
session.createQuery("update Student set email='dylan@gmail.com' where  firstName='Dylan'").executeUpdate();

Delete Objects

1
2
3
4
5
6
// retrieve a student
int studentId = 5;
Student myStudent = session.get(Student.class, studentId);

// delete
session.delete(myStudent);
1
session.createQuery("delete from Student where id=1").executeUpdate();

Reference: Udemy, Spring & Hibernate for Beginners (including SpringBoot)