What is Hibernate?
Hibernate is an ORM (Object-Relational Mapping) framework for Java, which simplifies the
interaction between Java applications and relational databases. It enables developers to work
with database records using Java objects, hiding the complexity of SQL queries.
JPA (Java Persistence API)
● JPA is a Java specification for accessing, persisting, and managing data between Java
objects and relational databases. Hibernate is one of the most popular implementations
of JPA.
Key Features of Hibernate:
1. ORM (Object-Relational Mapping)
● Hibernate maps Java objects to database tables and vice versa. Each class is
mapped to a corresponding database table, and each field of the class is mapped to a
column in the table. This allows developers to work with Java objects instead of directly
dealing with SQL queries.
2.HQL (Hibernate Query Language)/JPQL(Java Persistence Query
Language)
● Hibernate introduces its own query language called HQL, which is similar to SQL but
works with objects instead of tables. HQL allows developers to write object-oriented
queries using the class and property names, making it easier to retrieve and manipulate
data.
3. Automatic Table Generation
● Hibernate can automatically generate database schema (tables) based on the
mappings between Java classes and database tables. This feature is useful when
setting up a new project or migrating to a new database.
4.Caching
● Hibernate provides a caching mechanism to improve performance by reducing
database access.
○ First-level cache:
○ Second-level cache:
5.Lazy and Eager Loading
● Lazy Loading: Hibernate fetches data on demand, meaning it loads related data only
when it is explicitly accessed. This improves performance by fetching only the necessary
data.
● Eager Loading: In contrast, eager loading retrieves all related data in a single query,
which is useful when all the data is required upfront.
6.Support for Associations
● Hibernate supports associations between entities, such as One-to-One, One-to-Many,
Many-to-One, and Many-to-Many relationships. These can be mapped using
annotations or XML configurations.
○ One-to-One: Maps a one-to-one relationship between two entities.
○ One-to-Many / Many-to-One: Maps a one-to-many or many-to-one relationship.
○ Many-to-Many: Maps a many-to-many relationship between two entities.
7. Database Independence
● Hibernate provides database independence by allowing the same application code to
work with different databases (e.g., MySQL, Oracle, PostgreSQL) with minimal or no
code changes. Hibernate generates SQL queries based on the underlying database
dialect.
8. Exception Handling
● Hibernate handels the SQL Exception
Hibernate vs JDBC:
Hibernate JDBC
Abstracts SQL queries using HQL Direct interaction with SQL
and object mapping queries
Yes, supports ORM by mapping Java No ORM, uses raw SQL
objects to DB queries
Generates SQL automatically; Requires manual SQL writing
reduces SQL writing
Supports caching, lazy loading, and No caching, no optimization
batch fetching strategies
Built-in transaction management Relies on Java code for
transactions
Hibernate is database-agnostic JDBC code may need
changes for each DB
Faster, less boilerplate code Slower, requires more manual
effort
Requires configuration for ORM and Minimal configuration needed
mapping
EntityManagerFactory
● EntityManagerFactory is a factory class that creates instances of EntityManager. It is
a thread-safe, heavyweight object designed for long-term use and should be created
once per application (or persistence unit) and used throughout the application's lifecycle.
● The EntityManagerFactory provides a way to create and manage multiple
EntityManager instances, which are used to interact with the database.
● It is typically set up when the application starts and closed when the application shuts
down, as creating it is expensive in terms of resources.
EntityManager
● EntityManager is the main interface used to interact with the persistence context. It
manages the lifecycle of entity instances, handles database operations (CRUD), and
acts as a bridge between Java objects and database rows.
● It allows developers to create, read, update, and delete entities (CRUD operations).
● It also provides APIs for running queries (both JPQL and native SQL) and managing the
persistence context.
Key Methods:
● persist(): Save a new entity.
● find(): Find an entity by its primary key.
● merge(): Update an existing entity.
● remove(): Delete an entity from the database.
● createQuery(): Create a JPQL or SQL query.
Example:
3. EntityTransaction
● EntityTransaction is responsible for managing transactions in JPA. A transaction
ensures that a group of database operations are executed as a single unit of work, either
all succeeding or all failing (rollback), to maintain data consistency.
● The EntityTransaction interface provides methods to begin, commit, and roll back
database transactions.
● Transactions allow multiple database operations (e.g., inserts, updates) to be treated as
a single atomic unit.
Key Methods:
● begin(): Start a new transaction.
● commit(): Commit the current transaction, writing all changes to the database.
● rollback(): Roll back the current transaction, undoing all changes made during the
transaction.
Example:
What is an Entity Class?
● An entity class is a lightweight, persistent domain object in JPA that typically represents
a table in a relational database.
Requirements for Entity Classes
An entity class must follow these requirements.
● The class must be annotated with the javax.persistence.Entity annotation.
● The Class Must Have a No-Argument Constructor
● The Class Must Have an Identifier (Primary Key)
● Entity Class Must Not Be Final
● Fields Should Be Private with Getters and Setters
● Entity Class Must Not Be Enum or Interface
● the class must implement the Serializable interface.
JPA Annotations - Hibernate
Annotations
1. @Entity:
- Marks a Java class as an entity, indicating that instances of this class will be
persisted to the database.
2. **@Table:**
- Specifies the details of the database table that will be used to persist the entity.
3. **@Id:**
- Marks a field as the primary key of the entity.
4. **@GeneratedValue:**
- Specifies the strategy used to generate values for the primary key.
5. **@Column:**
- Maps a field to a database column and allows you to specify column details.
6. **@ManyToOne, @OneToMany, @ManyToMany: @onetoone**
- Define relationships between entities.
```
```
```
```
```
@CreationTimestamp and @UpdateTimestamp:
● Automatically populates the field with the current timestamp during entity
creation or update.
@Entity
public class MyClass {
@Id
private Long id;
@CreationTimestamp
private Timestamp createdOn;
@UpdateTimestamp
private Timestamp updatedOn;
// other fields
}
@OrderBy: Sort your data using @OrderBy annotation. In example below, it will sort all
employees_address by their id in ascending order.
@OrderBy("id asc")
1. private Set employee_address;
@Lob: Large objects are declared with @Lob.
@Lob
public String getEmployeeAddress() {
return employeeAddress;
2. }
package com;
import java.io.Serializable; // Hibernate requires entity classes to implement Serializable
import javax.persistence.*; // Required Hibernate/JPA annotations
/**
* The Employee entity class represents an employee in the system.
* It is mapped to the 'employees' table in the database.
*/
@Entity // Marks this class as a persistent entity
@Table(name = "employees") // Maps this class to the 'employees' table
public class Employee implements Serializable {
private static final long serialVersionUID = 1L; // Ensures that the class is serializable
/**
* The unique identifier for each employee.
* This field is mapped to the 'id' column and is auto-generated.
*/
@Id // Marks this field as the primary key
@GeneratedValue(strategy = GenerationType.IDENTITY) // Specifies the generation strategy
for the primary key
@Column(name = "id") // Maps this field to the 'id' column in the 'employees' table
private Long id;
/**
* The first name of the employee.
* This field is mapped to the 'first_name' column in the database.
*/
@Column(name = "first_name", nullable = false, length = 50) // Specifies the column name,
nullability, and max length
private String firstName;
/**
* The last name of the employee.
* This field is mapped to the 'last_name' column.
*/
@Column(name = "last_name", nullable = false, length = 50)
private String lastName;
/**
* The email of the employee.
* This field is mapped to the 'email' column, with a uniqueness constraint.
*/
@Column(name = "email", nullable = false, unique = true, length = 100)
private String email;
/**
* The salary of the employee.
* This field is mapped to the 'salary' column.
*/
@Column(name = "salary")
private Double salary;
// Default constructor - required by Hibernate
public Employee() {
}
// Parameterized constructor for ease of object creation
public Employee(String firstName, String lastName, String email, Double salary) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.salary = salary;
}
// Getter and Setter methods for each field
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ",
email=" + email + ", salary=" + salary + "]";
}
}
Key Rules and Best Practices:
1. @Entity Annotation: Marks the class as a JPA entity.
2. @Table(name = "employees"): Maps the class to the table employees.
3. Primary Key (@Id): Each entity requires a primary key.
4. @GeneratedValue: Specifies how the primary key should be generated (e.g., AUTO,
IDENTITY, SEQUENCE).
5. Field Mapping (@Column): Defines the column in the database that the field will be
mapped to.
6. Serializable: Entity classes must implement Serializable.
7. Nullability and Uniqueness: Fields can be marked as nullable = false, unique
= true for constraints.
8. Default Constructor: Required by Hibernate for proxy creation.
9. Getter and Setter Methods: Used to access and mutate entity fields.
Hibernate Mapping:
Hibernate mapping defines the relationship between Java classes and database tables. It
specifies how attributes of a Java class map to columns in a database table. Hibernate supports
several types of mappings:
1. One-to-One Mapping (@OneToOne)
2. One-to-Many Mapping (@OneToMany)
3. Many-to-One Mapping (@ManyToOne)
4. Many-to-Many Mapping (@ManyToMany)
1. One-to-One Mapping
Represents a one-to-one relationship between two entities. For example, a User has one
Profile.
2. One-to-Many Mapping
Represents a one-to-many relationship. For example, a Department has many Employees.
3. Many-to-One Mapping
Represents the inverse of a one-to-many relationship. For example, many Employees belong
to one Department. (This is shown in the above example under Employee.)
4. Many-to-Many Mapping
Represents a many-to-many relationship. For example, a Student can enroll in many
Courses, and each Course can have many Students.
@OneToOne, @OneToMany, @ManyToOne, @ManyToMany: Define relationships.
@JoinColumn: Specifies the foreign key column.
@JoinTable: Specifies the join table for many-to-many relationships.
@MappedBy: Specifies the field in the mapped entity that owns the relationship.
Eager/Lazy Loading in Hibernate
In Hibernate, the `fetch` attribute is used to specify how data should be
fetched from the database when querying for entities and their associations.
The `fetch` attribute is commonly applied to the `@OneToMany`,
`@ManyToOne`, and `@OneToOne` annotations.
It defines the strategy for retrieving associated entities.
Here are the main fetch types in Hibernate:
1. **FetchType.EAGER:**
- Eager fetching loads the associated entities immediately along with the
owning entity. It retrieves all the data at once.
2. **FetchType.LAZY:**
- Lazy fetching defers(postpone) the loading of associated entities until they
are explicitly accessed. It loads the associated data on-demand.
**Default Fetch Type:**
- If you don't explicitly specify the fetch type, Hibernate uses a default fetch
type.
For `@OneToMany` and `@ManyToMany` associations, the default is
`FetchType.LAZY`.
For `@ManyToOne` and `@OneToOne` associations, the default is
`FetchType.EAGER`.
@GeneratedValue
● In Hibernate, the `@GeneratedValue` annotation is used to specify how
the primary key of an entity should be generated.
● It is typically applied to the field or property that represents the primary
key of an entity.
● The `@GeneratedValue` annotation is often used in conjunction with
the `@Id` annotation.
Here are some common strategies for generating primary key values:
1. **GenerationType.IDENTITY:**
- Indicates that the primary key should be generated by the database. It is
suitable for databases that support auto-incrementing columns.
```
2. **GenerationType.SEQUENCE:**
- Uses a database sequence to generate unique key values. This strategy is
suitable for databases that support sequences.
Hibernate - Caching
● Caching in Hibernate refers to the technique of storing frequently accessed
data in memory to improve the performance of an application
● It reduces the time taken to obtain the required data — as it fetches from
memory instead of directly hitting the database
There are mainly two types of caching:
● First level cache
● Second-level cache
First-Level Cache: This cache is associated with the EntityManager or
Session and is maintained within the scope of a single database
transaction. It is enabled by default and helps reduce redundant database
queries within the same transaction.
Second-Level Cache: This cache is shared across multiple
EntityManager or Session instances. It provides a more global cache
that can be used to store entities, collections, and query results. Enabling
second-level cache involves configuring a caching provider (e.g., Ehcache,
Infinispan).
Second level cache
EH cache
Os cache
Swarm cache
Jboss cache
The Hibernate Query Language (HQL) and Java Persistence Query
Language (JPQL) are both object model focused query languages
similar in nature to SQL
Query Interface
It is an object oriented representation of Hibernate Query. The object of Query can be
obtained by calling the createQuery() method EntityManager interface.
1. public Object getSingleResult() Execute a SELECT query that returns a single
result.
2. public List getResultList() Execute a SELECT query and return the query results
as a List.
3. public Query setParameter(int position, Object value) it sets the value to the
JDBC style query parameter.
4. public Query setParameter(String name, Object value) it sets the value to a
named query parameter.
EntityManager.createQuery(“query”)
Named Parameters in Queries
Positional Parameters in Queries
You may use positional parameters instead of named parameters in queries. Positional
parameters are prefixed with a question mark (?) followed the numeric position of the parameter
in the query. The Query.setParameter(integer position, Object value) method
is used to set the parameter values.
“SELECT c FROM Customer c WHERE c.name= ?1”)
.setParameter(1, name)
.getResultList();
HQL (Hibernate Query Language) is similar to JPQL but is specific to Hibernate, which is
a popular JPA provider. Here are some example HQL queries for Hibernate:
SELECT e FROM EntityName e
SELECT e.field1, e.field2 FROM EntityName e
SELECT e FROM EntityName e WHERE e.field = :value
SELECT e FROM EntityName e ORDER BY e.field ASC
SELECT e FROM EntityName1 e1 JOIN e1.entityName2 e2 WHERE e2.field
= :value
SELECT e FROM EntityName e WHERE e.field = :parameter
SELECT AVG(e.field) FROM EntityName e
SELECT e.field, COUNT(e) FROM EntityName e GROUP BY e.field HAVING
COUNT(e) > 1
SELECT e FROM EntityName e WHERE e.field IN (SELECT e2.field FROM
EntityName2 e2 WHERE e2.otherField = :value)
SELECT e FROM EntityName e WHERE e.field BETWEEN :minValue AND
:maxValue
SELECT e FROM EntityName e WHERE e.field BETWEEN :minValue AND
:maxValue
SELECT e FROM EntityName e WHERE e.field BETWEEN :minValue AND
:maxValue
SELECT e FROM EntityName e WHERE e.field LIKE :pattern
SELECT e FROM EntityName e WHERE e.field LIKE :pattern
SELECT e FROM EntityName e WHERE e.field IS NULL
SELECT e FROM EntityName e WHERE e.field BETWEEN :minValue AND
:maxVal
String hqlUpdate = "UPDATE EntityName e SET e.field = :newValue
WHERE e.id = :entityId";
String hqlDelete = "DELETE FROM EntityName e WHERE e.id =
:entityId";
Detailed Flow of the Lifecycle:
1. Transient: An object is created using the new operator but is not saved to the database.
2. Persistent: When EntityManager.persist() or Session.save() is called, the
transient object becomes persistent and is saved in the database.
3. Detached: If the EntityManager or Session is closed, the object becomes detached.
The database no longer tracks changes to the detached object.
4. Removed: If EntityManager.remove() or Session.delete() is called on a
persistent entity, it will be marked for deletion. After committing the transaction, it is
deleted from the database and becomes transient.
Hibernate/JPA Operations that Change States:
1. persist() / save(): Moves the entity from Transient to Persistent state.
2. remove() / delete(): Moves the entity from Persistent to Removed state.
3. merge() / update(): Re-attaches a detached entity back to the Persistent state.
4. detach() / evict() / clear(): Moves the entity from Persistent to Detached state.
5. find() / get(): Retrieves an entity from the database and puts it in Persistent state.