Section 1

Learning Objectives:

In this presentation, we will get to know the Java persistence standard based on Hibernate. By the end of this session, learners will be able to:

  • Explain Object-Relational Mapping (ORM).

  • Explain the Hibernate Application Architecture and Hibernate - Annotations.

  • Describe how to use JPA to store and manage Java objects in a relational database.

  • Demonstrate the JPA with Hibernate as Implementation.

  • Demonstrate setting up a Hibernate project.

  • Describe Hibernate Query Object (HQO) and Hibernate Query Language (HQL).

  • Demonstrate how to use Hibernate Query Object (HQO).

Table of Contents

  • Setting up a Hibernate.

  • Entity/POJO/Model Classes

  • Hibernate Application workflow.

  • Hibernate - Annotations.

  • Hibernate Query Object / Hibernate Query Language

  • HQL - Interfaces

  • Execution HQL Queries

  • HQL Methods

  • Problem with HQL and SQL

  • Overview of Hibernate Named Query

  • Advantages of Named Queries

  • JDBC vs. Java Hibernate

  • Object Relational Mapping (ORM)

  • Java Persistence API (JPA)

  • Overview of Java Hibernate

  • Hibernate with JPA.

  • Hibernate Application Architecture.

    • Persistent objects.

    • Configuration.

      • Hibernate Configuration Files

      • Specify Exact Database Dialect

      • Hibernate Configuration Property

    • Session Factory in Hibernate

    • Session in Hibernate

    • Important “Session Methods”

    • Transaction

Object Relational Mapping

Object Relational Mapping (ORM) is the concept/process of converting data from object-oriented language to a relational database, and vice versa.

ORM translates the programming code attributes (variables) into the columns in the table. It is good for managing various database operations, such as insertion, update, and deletion effectively.

The mapping between the object model and the relational database should be as follows:

  • Class <-> Table.

  • Java Object <-> Row.

  • Class Attribute <-> Column.

Java Persistence API

  • Java Persistence API (JPA) is the Object-Relational Mapping (ORM) standard for storing, accessing, and managing Java objects in a relational database.

  • JPA is only a specification; it is not an implementation, but several implementations are available. Popular implementations include Hibernate, EclipseLink, Apache OpenJPA, and many more.

  • JPA permits the developer to work directly with objects rather than with SQL statements. The JPA implementation is typically called a persistence provider.

  • JPA is the EE standard specification for ORM in Java EE.

  • JPA API is a set of rules and a framework to set interfaces for implementing ORM.

Overview of Java Hibernate

Hibernate is an implementation of JPA API, and uses ORM techniques. In that, we can use the standard JPA API, and configure applications to use Hibernate as the provider of the specification under the covers. Hibernate provides more features beyond what JPA specifies:

  • The Hibernate framework consists of several components such as Hibernate ORM, Hibernate Search, Hibernate Validator, Hibernate CGM, and Hibernate Tools. In this course, we will use Hibernate ORM, which is the core component of the Hibernate framework for mapping Java model classes.

  • JDBC is not object-oriented; rather, we are dealing with values means of primitive data. In Hibernate, each record is represented as an Object, but in JDBC, each record is no more than data, which is nothing but primitive values.

  • Hibernate maps Java classes to database tables, and from Java data types to SQL data types. Hibernate maps also relieve the developer from the majority of common data persistence-related programming tasks. This is especially beneficial for developers with limited knowledge of SQL.

Hibernate with JPA

  • JPA is a specification for persistence providers to implement. Hibernate is one such implementation of JPA specification. We can annotate our classes as much as we like with JPA annotations; however, without an implementation, nothing will happen.

  • Think of JPA as the guidelines/specification that must be followed, or as an interface while Hibernate’s JPA implementation is code that meets the API, as defined by JPA, providing the “under-the-hood” functionality.

  • When we use hibernate with JPA, we are actually using the Hibernate JPA implementation. The benefit of this is that we can swap out Hibernate’s implementation of JPA for another implementation of the JPA specification.

  • When we use straight Hibernate, we lock into the implementation because other ORMs may use different methods/configurations and annotations; therefore, we cannot just switch over to another ORM.

Hibernate Application Architecture

Hibernate has a layered architecture, which helps the user to operate without having to know the underlying APIs. Hibernate makes use of the database and configuration data to provide persistence services (persistent objects) to the application.

Let’s understand what each block represents in detail:

  • Persistent Objects: Plain Old Java Objects (POJOs), which get persisted as one of the rows in the related table in the database by Hibernate. They can be configured in configuration files (hibernate.cfg.xml or hibernate.properties) or annotated with @Entity annotations.

Configuration

Configuration: A class, which is present in the org.hibernate.cfg package. The configuration object is the first Hibernate object; it activates the Hibernate framework and reads both configuration files and mapping files. It is usually created only once during application initialization, and represents a configuration file (hibernate.cfg.xml) or properties file(hibernate.properties).

The configuration object provides two keys components:

  • Database Connection: Handled through one or more configuration files supported by Hibernate; these files are hibernate.properties or hibernate.cfg.xml.

Configuration cfg = new Configuration();
cfg.configure(); // read both cfg file and mapping files

The configuration object is used to create a SessionFactory object in Hibernate.

SessionFactory factory=cfg.buildSessionFactory();

Hibernate Configuration Files

Database details and mapping file details are specified in hibernate.cfg.xml file. The Hibernate engine uses these files to generate Database specific SQL syntax.

Example - hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 5.3//EN" "<http://www.hibernate.org/dtd/hibernate-configuration-5.3.dtd>">
<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/databasename</property>
        <property name="connection.username">root</property>
        <property name="connection.password">password</property>
        <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
        <property name="hibernate.show_sql">true</property>
        <mapping class="com.test.hib.model.User"/>
        <mapping class="com.perscholas.model.Employee"/>
    </session-factory>
</hibernate-configuration>

Specify Exact Database Dialect

Hibernate uses the SQL syntax of the target database to create tables accordingly; therefore, it is important to specify database dialect information exactly to match the type of underlying database. Otherwise, you will get an error or an undesired behavior.

<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

Hibernate Configuration Property

To use Hibernate Forward Engineering, you need to specify the hibernate.hbm2ddl.auto property in the Hibernate configuration file. The “hibernate.hbm2ddl.auto” property accepts the following values:

  • create: If the value is created, Hibernate creates a new table in the database when the SessionFactory object is created. If a table exists in the database with the same name, it deletes the table along with the data and creates a new table.

  • update: If the value is updated, Hibernate first validates whether the table is present in the database or not. If it is present, Hibernate alters that table per the changes; if it is not present, Hibernate creates a new one.

  • validate: If the value is validated, Hibernate only verifies whether the table is present. If the table does not exist, Hibernate throws an exception.

  • create-drop: If the value is create-drop, Hibernate creates a new table when SessionFactory is created, performs the operation, and deletes the table when SessionFactory is destroyed. This value is used for testing the Hibernate code.

  • none: It does not make any changes to the schema.

<property name=”hibernate.hbm2ddl.auto”>create</property>

Session Factory in Hibernate

SessionFactory() Object:

  • SessionFactory is an interface, which is present in the org.hibernate package.

  • Configuration object is used to create a SessionFactory object. The SessionFactory is a thread-safe object and is used by all of the threads of an application.

  • It is usually created during application start-up and kept for later use. We would need one SessionFactory object per database, using a separate configuration file. So, if you are using multiple databases, you would have to create multiple SessionFactory objects.

  • The SessionFactory in Hibernate is responsible for the creation of Session objects.

SessionFactory factory=cfg.buildSessionFactory();

Session in Hibernate

Session() Object:

  • Session is an interface, which is present in the org.hibernate package. A Session is used to get a physical connection with a database. A Session object is created based upon a SessionFactory() object.

  • A Session() is designed to be instantiated each time an interaction is needed with the database.

  • The Session objects should not be kept open for a long time because they are not usually thread-safe, and they should be created and destroyed as needed.

  • A Session object is used to perform Create, Read, Update, and Delete(CRUD) operations for instances of mapped entity classes. Instances may exist in one of three states:

    • Transient: never persistent; not associated with any Session.

    • Persistent: associated with a unique Session.

    • Detached: previously persistent; not associated with any Session.

Session session = factory.buildSession();

Transaction

Transaction enables you to achieve data consistency and rollback in case something unexpected happens. A transaction can be described by Atomicity, Consistency, Isolation, and Durability (ACID) properties. It maintains abstraction from the transaction implementation (JTA,JDBC).

Transaction tx=session.beginTransaction();
tx.commit();

The methods of Transaction interface are as follows:

  1. void begin() starts a new transaction.

  2. void commit() ends the unit of work unless we are in FlushMode.NEVER.

  3. void rollback() forces this transaction to rollback.

  4. void setTimeout(int seconds) sets a transaction timeout for any transaction started by a subsequent call to begin on this instance.

  5. boolean isAlive() checks if the transaction is still alive.

  6. void registerSynchronization(Synchronization s) registers a user synchronization callback for this transaction.

  7. boolean wasCommited() checks if the transaction is committed successfully.

  8. boolean wasRolledBack() checks if the transaction is rolled back successfully.

Query Object

Query Interface:

  • Query is an interface that presents inside org.hibernate package.

  • A Query instance is obtained by calling Session.createQuery() method.

  • Query objects use SQL or Hibernate Query Language (HQL) to retrieve data from the database and create objects. A Query instance is used to bind query parameters, limit the number of results returned by the query, and finally, to execute the query.

Query query=session.createQuery();

Setting up a Hibernate

  1. Create Java Maven Project.

  2. Configure Maven Dependencies for Hibernate and Database in pom.xml file.

<!-- <https://mvnrepository.com/artifact/org.hibernate/hibernate-core> -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.5.7.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-annotations</artifactId>
    <version>3.5.5-Final</version>
</dependency>
<!-- <https://mvnrepository.com/artifact/mysql/mysql-connector-java> -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.25</version>
</dependency>

Maven automatically downloads the required JAR files.

Entity/POJO/Model Classes

  • Entity is a Java object that is going to be persisted. Entity classes are decorated with Java annotations such as @Entity, @Id, @Table, or @Column.

  • Entities are nothing but beans or Models, and they contain default constructor, setter, and getter methods for the attributes or private variables (class variables).

Hibernate Application Workflow

Phase 1 Composed of...

  • Add Maven dependencies for Hibernate and mysql

  • POJO Classes:

    • Creating Entities - Entities are nothing but beans or Models, and they contain default constructor, setter, and getter methods of those attributes. (Note: We will be handling this via annotations.)

  • DAO/Service Classes containing service methods:

    • Create, Update, Delete, or Find a record.

Phase 2 Composed of...

  • Mapping File: Hibernate Configuration:

    • Configurations - Database connection information, schema level settings, and entity mapping, using the mapping file (hibernate.properties or hibernate.cfg.xml).

Hibernate - Annotations

Annotations:

  • We can write configurations using annotations. The annotations are used for classes, properties, and methods. Annotations start with the ‘@’ symbol, and are declared before the class, property, or method is declared.

  • Hibernate Annotations is a powerful way to provide the metadata for the Object and Relational Table mapping. Annotations used in our examples:

AnnotationDescription

@Entity

This annotation indicates that the class is mapped to a database table. By default, the ORM framework understands that the class name is the same as the table name. The @Entity annotation must be placed before the class definition.

@Table

This annotation is used if the class name is different than the database table name, and it must be placed before the class definition.

@Id

This annotation specifies that a field is mapped to a primary key column in the table.

@Basic

This annotation tells JPA the below variable is a regular attribute.

Hands-On Lab

Find the GLAB - 305.4.1 - Hibernate Project Demonstration on Canvas under the Assignment section.

  • Important note:

    • The instructor should give a demonstration of the above lab in the class.

    • If you have any technical questions while performing the lab activity, ask your instructors for assistance.

Practice Assignment

hibernate.cfg.xml

  • Using Hibernate, create a Department Model with the following attributes:

    • int did

    • String name

    • String state

  • Using Hibernate, create the relevant services for this Model (create, update name/state, find, and delete).

  • Do not forget to add your model to the configuration file.

If you have any technical questions while performing this practice assignment, ask your instructors for assistance.

Knowledge Check

  1. What is the difference between ORM, JPA, and Hibernate?

  2. Why do we need Hibernate instead of JDBC?

Summary

Object Relational Mapping (ORM) is a concept/process of converting the data from Object Oriented Language to relational database, and vice versa. In Java, this is performed with the help of reflection and JDBC.

Java Persistence API is one step above ORM. It has a high-level API and specification requirement so that different ORM tools can implement it and provide the flexibility to change the implementation from one ORM to another (e.g., if an application uses the JPA API and implementation is hibernate).

Last updated