Hibernate Copyright and Usage Guidelines
Hibernate Copyright and Usage Guidelines
Hibernate by ByteMart
Copyright © 2025 ByteMart. All rights reserved.
Copyright Notice
This book, Hibernate by ByteMart, including all associated content—text, illustrations, code
samples, diagrams, and examples—is the exclusive intellectual property of ByteMart.
No part of this publication may be copied, stored, or transmitted in any form—electronic,
mechanical, photocopied, recorded, or otherwise—without prior written permission from
ByteMart.
This copyright is protected under international intellectual property laws. Any unauthorized
reproduction, sharing, or distribution of any part of this book is strictly prohibited and may
result in legal action, including claims for damages and recovery of legal costs.
For permission inquiries, please contact:
Email: contact@[Link]
Website: [Link]
Disclaimer
This book is provided "as is" without any guarantees or warranties, express or implied. While
every effort has been made to ensure accuracy and completeness, ByteMart makes no
representations regarding the currentness, performance, or applicability of the information.
The contents are intended for educational purposes only. As technologies such as
Hibernate are constantly evolving, readers are advised to consult the official documentation
for the most up-to-date information and adapt the examples accordingly.
Warning
This book is the result of significant expertise and effort. Any act of intellectual property
theft—including plagiarism, unauthorized redistribution, or content misuse—will result in
immediate legal action under applicable copyright and IP laws.
ByteMart assumes no responsibility for any loss, damage, or consequences resulting from
the use of the information or code provided in this publication.
Contact Information
For permissions, collaborations, or support inquiries:
• Email: contact@[Link]
• Website: [Link]
Hibernate
Table of Contents
1. Introduction of Hibernate
3. Hibernate Features
7. Association Mapping
Many-to-Many Mapping
8. Version Mapping
9. Timestamp Mapping
Polymorphic Query
ACID Property
Hibernate 1
by
ByteMart
Transaction Concurrency Problem & Solutions
Types of Transactions
JDBC Transaction
JTA Transaction
CMT Transaction
Exploring SessionFactory
Object States
Hibernate 2
by
ByteMart
4. Performance: It includes caching mechanisms that enhance application
performance.
Session
The object represents a single unit of work with the database. It is used
to create, read, and delete persistent objects.
Transaction
The interface is used to manage transactions in Hibernate. It
abstracts the underlying transaction management of the database.
Query
The interface allows the execution of HQL (Hibernate Query Language)
or SQL queries against the database.
Criteria
The API is a more object-oriented way to create and execute queries.
Configuration
Hibernate 3
by
ByteMart
The class represents the entire configuration for Hibernate. It is
used to configure the .
2. Hibernate Query Language (HQL): HQL is similar to SQL but works with
Java objects instead of tables.
5. Lazy Loading: Data is fetched on-demand, reducing the initial load time.
Step-by-Step Setup
Hibernate 4
by
ByteMart
1. Add Hibernate Dependencies
If using Maven, add the following dependencies to your :
<dependency>
<groupId>[Link]</groupId>
<artifactId>hibernate-core</artifactId>
<version>[Link]</version>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>[Link]</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
Hibernate 5
by
ByteMart
<property name="[Link]">update</pro
perty>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</propert
y>
package [Link];
Hibernate 6
by
ByteMart
<property name="name" column="NAME"/>
<property name="department" column="DEPARTMENT"/>
<property name="salary" column="SALARY"/>
</class>
</hibernate-mapping>
package [Link];
import [Link];
import [Link];
static {
try {
sessionFactory = new Configuration().configure
().buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
package [Link];
import [Link];
import [Link];
import [Link];
Hibernate 7
by
ByteMart
import [Link];
try {
transaction = [Link]();
[Link]();
} catch (Exception e) {
if (transaction != null) {
[Link]();
}
[Link]();
} finally {
[Link]();
}
}
}
1.6 Summary
Hibernate is a powerful ORM tool that simplifies Java application development
by handling database interactions efficiently. It abstracts complex SQL queries
into high-level Java objects, offers robust transaction management, supports
various types of caching, and provides a rich query language (HQL). Setting up
Hibernate 8
by
ByteMart
Hibernate involves adding dependencies, configuring the file,
creating model classes, and writing mapping files.
By using Hibernate, developers can focus more on business logic rather than
dealing with intricate database operations, leading to more maintainable and
scalable applications.
Hibernate 9
by
ByteMart
Example of JDBC Usage
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
while ([Link]()) {
[Link]("ID: " + [Link]
t("id"));
[Link]("Name: " + [Link]
String("name"));
[Link]("Department: " + resultS
[Link]("department"));
[Link]("Salary: " + resultSet.g
etDouble("salary"));
}
} catch (SQLException e) {
[Link]();
}
}
}
Hibernate 10
2.3 Overview of Hibernate
What is Hibernate?
Hibernate is an open-source ORM (Object-Relational Mapping) framework for
Java. It simplifies database interactions by mapping Java classes to database
tables. Hibernate abstracts the underlying SQL, allowing developers to work
with high-level Java objects.
package [Link];
import [Link];
import [Link];
Hibernate 11
Transaction transaction = null;
try {
transaction = [Link]();
[Link](employee);
[Link]();
} catch (Exception e) {
if (transaction != null) {
[Link]();
}
[Link]();
} finally {
[Link]();
}
}
}
Hibernate 12
First-level and second-level
Caching No built-in caching
caching
When you need fine-grained control over SQL and database operations.
When you want to leverage ORM features like caching, lazy loading, and
automatic table creation.
2.7 Summary
JDBC and Hibernate are both powerful tools for database interaction in Java
applications, each with its own strengths and use cases. JDBC offers low-level
control and is suitable for simple applications and scenarios requiring direct
Hibernate 13
SQL management. Hibernate, on the other hand, provides a high-level
abstraction that simplifies database operations through ORM, making it ideal for
complex and large-scale applications.
Example:
Hibernate 14
[Link]("salary", 50000);
List<Employee> results = [Link]();
<property name="[Link]">update</property>
3.2.5 Caching
Hibernate supports both first-level (Session) and second-level
(SessionFactory) caching to improve performance by reducing database
access.
Hibernate 15
Infinispan.
<property name="[Link].use_second_level_cache">tru
e</property>
<property name="[Link].factory_class">org.h
[Link]</property>
Eager Loading: Associated entities are loaded immediately with the parent
entity.
Example:
@Entity
public class Department {
@OneToMany(fetch = [Link], mappedBy = "departme
nt")
private Set<Employee> employees;
}
Example:
Hibernate 16
throw e;
}
Example:
[Link]();
Employee employee = [Link]([Link], 1);
[Link](60000);
[Link]().commit();
One-to-Many Association:
@Entity
public class Department {
@OneToMany(mappedBy = "department")
private Set<Employee> employees;
}
@Entity
public class Employee {
@ManyToOne
@JoinColumn(name = "department_id")
private Department department;
}
Inheritance Mapping:
Hibernate 17
@Entity
@Inheritance(strategy = [Link])
public class Person {
@Id
private int id;
private String name;
}
@Entity
public class Employee extends Person {
private double salary;
}
HQL Query:
3.3 Summary
Hibernate 18
Hibernate offers a rich set of features that simplify database interactions,
enhance performance, and improve maintainability. Key features like ORM,
HQL, Criteria API, automatic table creation, caching, lazy and eager loading,
transaction management, automatic dirty checking, association and inheritance
mapping, and support for HQL and native SQL queries make Hibernate a
powerful framework for enterprise-level applications. By leveraging these
features, developers can build robust, scalable, and efficient applications with
ease.
4.2 Prerequisites
Before starting, ensure you have the following installed:
<dependencies>
<dependency>
<groupId>[Link]</groupId>
Hibernate 19
<artifactId>hibernate-core</artifactId>
<version>[Link]</version>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>[Link]</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
</dependencies>
Hibernate 20
y>
package [Link];
Hibernate 21
return department;
}
Hibernate 22
Create a utility class to initialize Hibernate and provide the . Save
it in the directory:
package [Link];
import [Link];
import [Link];
static {
try {
sessionFactory = new Configuration().configure
().buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
Hibernate 23
Session session = [Link]
().openSession();
Transaction transaction = null;
try {
transaction = [Link]();
[Link]();
} catch (Exception e) {
if (transaction != null) {
[Link]();
}
[Link]();
} finally {
[Link]();
}
}
}
4.5 Summary
This chapter demonstrated a simple example of using Hibernate with an
mapping file. We covered setting up the project, creating configuration and
Hibernate 24
mapping files, and performing basic CRUD operations. By following these
steps, you can create and run a Hibernate application that maps Java classes
to database tables, leveraging Hibernate's powerful ORM capabilities.
5.2 Prerequisites
Ensure you have the following installed:
<dependencies>
<dependency>
<groupId>[Link]</groupId>
<artifactId>hibernate-core</artifactId>
<version>[Link]</version>
</dependency>
Hibernate 25
<dependency>
<groupId>[Link]</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>[Link]</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
</dependencies>
Hibernate 26
<mapping class="[Link]"/>
</session-factory>
</hibernate-configuration>
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Entity
@Table(name = "EMPLOYEE")
public class Employee {
@Id
@GeneratedValue(strategy = [Link])
private int id;
Hibernate 27
public String getName() {
return name;
}
it in the directory:
package [Link];
import [Link];
import [Link];
Hibernate 28
static {
try {
sessionFactory = new Configuration().configure
().buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
try {
transaction = [Link]();
Hibernate 29
[Link](75000);
[Link]();
} catch (Exception e) {
if (transaction != null) {
[Link]();
}
[Link]();
} finally {
[Link]();
}
}
}
5.5 Summary
This chapter demonstrated how to use annotations with Hibernate to map Java
classes to database tables. We covered setting up the project, creating
configuration files, defining the entity with annotations, and performing basic
CRUD operations. Using annotations simplifies the configuration process and
enhances the readability of the mapping, making it easier to maintain and
manage.
Hibernate 30
Table Per Class Mapping
In this chapter, we will discuss these two strategies in detail and provide
examples for each.
6.1.2 Example
Consider an inheritance hierarchy with a base class and two subclasses
and .
package [Link];
import [Link].*;
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Person {
@Id
@GeneratedValue(strategy = [Link])
private int id;
private String name;
Hibernate 31
[Link] = id;
}
[Link]
package [Link];
import [Link];
@Entity
public class Employee extends Person {
private String department;
private double salary;
Hibernate 32
}
}
[Link]
package [Link];
import [Link];
@Entity
public class Customer extends Person {
private String loyaltyLevel;
<mapping class="[Link]"/>
<mapping class="[Link]"/>
<mapping class="[Link]"/>
Hibernate 33
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
try {
transaction = [Link]();
[Link]();
} catch (Exception e) {
if (transaction != null) {
[Link]();
}
[Link]();
Hibernate 34
} finally {
[Link]();
}
}
}
6.2.2 Example
Using the same , , and classes as before, we will now
package [Link];
import [Link].*;
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Person {
@Id
@GeneratedValue(strategy = [Link])
private int id;
Hibernate 35
private String name;
6.3 Summary
Hibernate 36
This chapter covered two inheritance mapping strategies in Hibernate:
Table Per Class Mapping: Each class in the hierarchy has its own table.
Table Per Concrete Class Mapping: Each concrete class has its own table,
and inherited fields are included in each table.
Many-to-Many Mapping
7.1.2 Example
Consider an example where each has one .
package [Link];
import [Link].*;
@Entity
Hibernate 37
public class Person {
@Id
@GeneratedValue(strategy = [Link])
private int id;
private String name;
@OneToOne
@JoinColumn(name = "address_id")
private Address address;
[Link]
Hibernate 38
package [Link];
import [Link].*;
@Entity
public class Address {
@Id
@GeneratedValue(strategy = [Link])
private int id;
private String street;
private String city;
Hibernate 39
Step 2: Create Hibernate Configuration
Add the annotated classes to your :
<mapping class="[Link]"/>
<mapping class="[Link]"/>
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
try {
transaction = [Link]();
Hibernate 40
[Link](address);
[Link]();
} catch (Exception e) {
if (transaction != null) {
[Link]();
}
[Link]();
} finally {
[Link]();
}
}
}
7.2.2 Example
Using the same and classes, we will now make the association
bi-directional.
Hibernate 41
package [Link];
import [Link].*;
@Entity
public class Person {
@Id
@GeneratedValue(strategy = [Link])
private int id;
private String name;
@OneToOne(mappedBy = "person")
private Address address;
Hibernate 42
}
}
[Link]
package [Link];
import [Link].*;
@Entity
public class Address {
@Id
@GeneratedValue(strategy = [Link])
private int id;
private String street;
private String city;
@OneToOne
@JoinColumn(name = "person_id")
private Person person;
Hibernate 43
public String getCity() {
return city;
}
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
Hibernate 44
try {
transaction = [Link]();
[Link]();
} catch (Exception e) {
if (transaction != null) {
[Link]();
}
[Link]();
} finally {
[Link]();
}
}
}
Hibernate 45
In a many-to-many mapping, multiple instances of one entity are associated
with multiple instances of another entity. This type of association typically
requires a join table.
7.3.2 Example
Consider an example where and entities have a many-to-many
relationship.
package [Link];
import [Link].*;
import [Link];
import [Link];
@Entity
public class Student {
@Id
@GeneratedValue(strategy = [Link])
private int id;
private String name;
@ManyToMany
@JoinTable(
name = "student_course",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_i
d")
)
private Set<Course> courses = new HashSet<>();
Hibernate 46
public void setId(int id) {
[Link] = id;
}
[Link]
package [Link];
import [Link].*;
import [Link];
import [Link];
@Entity
public class Course {
@Id
@GeneratedValue(strategy = [Link])
private int id;
private String title;
@ManyToMany(mappedBy = "courses")
private Set<Student> students = new HashSet<>();
Hibernate 47
// Getters and setters
public int getId() {
return id;
}
}
}
<mapping class="[Link]"/>
<mapping class="[Link]"/>
Hibernate 48
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
try {
transaction = [Link]();
Hibernate 49
[Link](course2);
[Link](student);
[Link]();
} catch (Exception e) {
if (transaction != null) {
[Link]();
}
[Link]();
} finally {
[Link]();
}
}
}
7.4 Summary
This chapter covered three types of association mappings in Hibernate:
We provided detailed examples and code for each type of mapping. These
mappings enable you to define complex relationships between entities and
leverage Hibernate's ORM capabilities to manage these associations efficiently.
Hibernate 50
Chapter 8: Version Mapping
Version mapping in Hibernate is a technique used to manage concurrent
access to data in a database. It ensures data consistency by using a versioning
mechanism that helps prevent the "lost update" problem, where multiple
transactions simultaneously modify the same data and the last transaction
overwrites the previous changes.
package [Link];
import [Link].*;
Hibernate 51
@Entity
public class Product {
@Id
@GeneratedValue(strategy = [Link])
private int id;
private String name;
private double price;
@Version
private int version;
Hibernate 52
}
<mapping class="[Link]"/>
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
try {
transaction = [Link]();
// Create a product
Product product = new Product();
[Link]("Laptop");
Hibernate 53
[Link](1500.00);
} catch (Exception e) {
if (transaction != null) {
[Link]();
}
[Link]();
} finally {
[Link]();
}
}
}
8.2.2 Explanation
The entity has a field, which Hibernate uses to manage
versioning.
Hibernate 54
When saving or updating a , Hibernate automatically checks the
version field to ensure data consistency.
[Link]
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
try {
transaction1 = [Link]();
transaction2 = [Link]();
Hibernate 55
Product product2 = [Link]([Link],
1);
} catch (LockAcquisitionException e) {
if (transaction2 != null) {
[Link]();
}
[Link]("Optimistic lock exception:
" + [Link]());
} finally {
[Link]();
[Link]();
}
}
}
8.3.1 Explanation
Two sessions are used to simulate concurrent updates.
The first session updates the product and commits the transaction.
8.4 Summary
Hibernate 56
Version mapping is a crucial feature in Hibernate for managing concurrent
access to entities. By using version properties and optimistic locking, Hibernate
ensures data consistency and prevents the "lost update" problem. This chapter
covered the basics of version mapping, provided a step-by-step
implementation example, and demonstrated how to handle
. Understanding version mapping helps in building robust
applications that handle concurrent data access effectively.
Data Integrity: Ensuring that the most recent changes are always reflected
in the data.
Hibernate 57
Consider an entity with and timestamp fields.
import [Link].*;
import [Link];
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = [Link])
private Long id;
@CreationTimestamp
@Column(updatable = false)
private LocalDateTime createdAt;
@UpdateTimestamp
private LocalDateTime updatedAt;
entity is persisted for the first time. This field is typically marked as
because its value should not change once set.
Hibernate 58
CREATE TABLE users (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDAT
E CURRENT_TIMESTAMP
);
Hibernate 59
[Link]();
}
import [Link].*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = [Link])
private Long id;
Hibernate 60
@CreationTimestamp
@Column(updatable = false)
private LocalDateTime createdAt;
@UpdateTimestamp
private LocalDateTime updatedAt;
@Version
private int version;
9.7 Conclusion
Timestamp mapping in Hibernate simplifies the management of creation and
update timestamps within your entities. By leveraging and
, you can automate this process, ensuring accurate and
consistent timestamp data for auditing and concurrency control.
In the next chapter, we will explore the Data Access Object (DAO) pattern and
how it can be implemented in Hibernate to separate the data persistence logic
from business logic, providing a cleaner and more modular codebase.
Hibernate 61
underlying database details. This separation of concerns helps in managing
and maintaining the codebase more effectively.
Hibernate 62
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>[Link]</version>
</dependency>
<!-- Other dependencies like JPA, MySQL Connector, etc.
-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
</dependencies>
Hibernate 63
ty>
<property name="[Link]">300</proper
ty>
<property name="hibernate.c3p0.max_statements">50</
property>
<property name="hibernate.c3p0.idle_test_period">30
00</property>
import [Link].*;
import [Link];
@Entity
@Table(name = "users")
Hibernate 64
public class User {
@Id
@GeneratedValue(strategy = [Link])
private Long id;
@CreationTimestamp
@Column(updatable = false)
private LocalDateTime createdAt;
@UpdateTimestamp
private LocalDateTime updatedAt;
import [Link];
import [Link];
import [Link];
import [Link];
Hibernate 65
import [Link];
import [Link];
public UserDaoImpl() {
sessionFactory = new Configuration().configure().bu
ildSessionFactory();
}
@Override
public void save(User user) {
Session session = [Link]();
Transaction transaction = [Link]
();
[Link](user);
[Link]();
[Link]();
}
@Override
public User findById(Long id) {
Session session = [Link]();
User user = [Link]([Link], id);
[Link]();
return user;
}
@Override
public List<User> findAll() {
Session session = [Link]();
List<User> users = [Link]("from User",
[Link]).list();
[Link]();
return users;
}
Hibernate 66
@Override
public void update(User user) {
Session session = [Link]();
Transaction transaction = [Link]
();
[Link](user);
[Link]();
[Link]();
}
@Override
public void delete(User user) {
Session session = [Link]();
Transaction transaction = [Link]
();
[Link](user);
[Link]();
[Link]();
}
}
import [Link];
public UserService() {
userDao = new UserDaoImpl();
}
Hibernate 67
[Link](username);
[Link](password);
[Link](user);
}
Hibernate 68
// Create users
[Link]("john_doe", "password123");
[Link]("jane_doe", "password456");
// Update a user
User user = [Link](1L);
if (user != null) {
[Link]([Link](), "john_doe_
updated", "newpassword123");
}
// Delete a user
[Link](1L);
}
}
}
10.5 Conclusion
Hibernate 69
The DAO pattern provides a clear and maintainable structure for managing data
access in Hibernate applications. By separating the data access logic from the
business logic, you can achieve a modular, reusable, and testable codebase.
The example provided demonstrates how to implement and use the DAO
pattern effectively with Hibernate, laying a solid foundation for building robust
applications.
In the next chapter, we will explore the Hibernate Query Language (HQL) and its
powerful features for querying the database in a more object-oriented way.
Hibernate 70
Query query = [Link](hql);
List<User> users = [Link]();
Example of QBC
Query<User> q = [Link](query);
List<User> users = [Link]();
Hibernate 71
@Entity
@Table(name = "users")
@NamedQueries({
@NamedQuery(name = "[Link]", query = "FROM Use
r"),
@NamedQuery(name = "[Link]", query = "FROM
User u WHERE [Link] = :username")
})
public class User {
// Entity fields and methods
}
Hibernate 72
Positional parameters are denoted by followed by the parameter index in the
HQL query.
[Link]();
[Link]();
Hibernate 73
[Link]([Link]());
}
Query<User> q = [Link](query);
List<User> users = [Link]();
[Link]();
[Link]();
[Link]();
[Link]();
Hibernate 74
[Link]([Link]());
11.5 Conclusion
Hibernate Query Language (HQL) provides a powerful and flexible way to
interact with your database through Hibernate's ORM capabilities. It supports a
wide range of querying options, including polymorphic queries, positional and
named parameters, and integrates seamlessly with SQL, Criteria API, Native
Queries, and Named Queries. By leveraging these tools, developers can write
more readable, maintainable, and efficient data access code.
In the next chapter, we will delve into handling primary keys in Hibernate,
covering simple, custom, and composite primary keys.
Hibernate 75
Hibernate supports several strategies for auto-generating primary keys:
import [Link].*;
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = [Link])
private Long id;
In this example, the field is the primary key, and its value is automatically
generated using the database's identity column.
import [Link].*;
@Entity
Hibernate 76
@Table(name = "employees")
public class Employee {
@Id
private Long id;
In this case, you need to ensure that the value is set manually before
persisting the entity.
Let's walk through a complete example of defining and using a simple primary
key in Hibernate.
Hibernate 77
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
</dependencies>
property>
<property name="hibernate.c3p0.idle_test_period">30
00</property>
Hibernate 78
<property name="[Link]">[Link]
alect.MySQL8Dialect</property>
import [Link].*;
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = [Link])
private Long id;
Hibernate 79
// Getters and setters
}
Creating an Employee
Reading an Employee
Updating an Employee
Hibernate 80
Deleting an Employee
// Create employee
createEmployee(session, "John Doe", "Engineering");
// Fetch employee
Employee employee = getEmployeeById(session, 1L);
[Link]("Employee: " + [Link]
());
// Update employee
updateEmployee(session, 1L, "John Doe", "Marketin
g");
Hibernate 81
// Delete employee
deleteEmployee(session, 1L);
// Verify deletion
Employee deletedEmployee = getEmployeeById(session,
1L);
if (deletedEmployee == null) {
[Link]("Employee successfully delet
ed");
}
[Link]();
[Link]();
}
}
12.5 Conclusion
Defining and using a simple primary key in Hibernate is straightforward and
essential for ensuring the uniqueness and integrity of database records. By
leveraging the and annotations, developers can easily
In the next chapter, we will explore custom primary keys and how to handle
more complex primary key requirements in Hibernate.
Hibernate 82
custom primary keys can be implemented using various strategies, including
custom sequences, UUIDs, and composite keys.
import [Link].*;
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = [Link], gen
erator = "custom_seq")
@SequenceGenerator(name = "custom_seq", sequenceName =
"custom_sequence", allocationSize = 1)
private Long id;
Hibernate 83
UUIDs (Universally Unique Identifiers) are 128-bit values that can be used to
uniquely identify records across distributed systems. They are particularly
useful when dealing with distributed databases or ensuring global uniqueness.
Example of UUID
First, add a dependency for UUID generation if not already included:
<dependency>
<groupId>[Link]</groupId>
<artifactId>hibernate-core</artifactId>
<version>[Link]</version>
</dependency>
import [Link].*;
import [Link];
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = [Link])
@Column(columnDefinition = "BINARY(16)")
private UUID id;
Hibernate 84
First, create the custom identifier generator:
import [Link]
entor;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link].*;
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "[Link]
[Link]")
private String id;
Hibernate 85
13.3 Practical Example
Let's walk through a complete example of defining and using a custom primary
key in Hibernate using a UUID strategy.
Hibernate 86
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="[Link].driver_class">
[Link]</property>
<property name="[Link]">jdbc:mysq
l://localhost:3306/your_database</property>
<property name="[Link]">your
_username</property>
<property name="[Link]">your
_password</property>
property>
<property name="hibernate.c3p0.idle_test_period">30
00</property>
Hibernate 87
<property name="[Link]">update</pro
perty>
import [Link].*;
import [Link];
@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue(strategy = [Link])
@Column(columnDefinition = "BINARY(16)")
private UUID id;
Creating an Employee
Hibernate 88
[Link](department);
[Link](employee);
[Link]();
}
Reading an Employee
Updating an Employee
Deleting an Employee
Hibernate 89
13.3.5 Testing the CRUD Operations
Create a simple test class to verify the CRUD operations.
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
// Create employee
createEmployee(session, "John Doe", "Engineering");
// Fetch employee
Employee employee = getEmployeeById(session, UUID.f
romString("your-uuid-string"));
[Link]("Employee: " + [Link]
());
// Update employee
updateEmployee(session, [Link]("your-uuid-
string"), "John Doe", "Marketing");
// Delete employee
deleteEmployee(session, [Link]("your-uuid-
string"));
Hibernate 90
// Verify deletion
Employee deletedEmployee = getEmployeeById(session,
[Link]("your-uuid-string"));
if (deletedEmployee == null) {
[Link]("Employee successfully delet
ed");
}
[Link]();
[Link]();
}
) {
Hibernate 91
[Link](name);
[Link](department);
[Link](employee);
}
[Link]();
}
Conclusion
Custom primary keys in Hibernate provide flexibility and control over how
entities are uniquely identified. By using strategies such as custom sequences,
UUIDs, and custom identifier generators, developers can tailor primary key
generation to meet specific requirements. The provided examples demonstrate
how to implement and test these custom primary key strategies effectively.
In the next chapter, we will explore composite primary keys, which are essential
for complex key structures involving multiple columns.
Hibernate 92
is often used in cases where a single column cannot uniquely identify a record,
especially in many-to-many relationships and complex business logic
scenarios.
import [Link];
import [Link];
// Default constructor
public EmployeeId() {}
// Parameterized constructor
public EmployeeId(Long employeeId, Long departmentId) {
[Link] = employeeId;
[Link] = departmentId;
}
Hibernate 93
[Link] = employeeId;
}
@Override
public int hashCode() {
return [Link](employeeId, departmentId);
}
}
import [Link].*;
@Entity
@IdClass([Link])
@Table(name = "employee_department")
public class EmployeeDepartment {
Hibernate 94
@Id
private Long employeeId;
@Id
private Long departmentId;
This approach involves embedding the composite key class directly into the
Hibernate 95
entity class.
import [Link];
import [Link];
import [Link];
@Embeddable
public class EmployeeDepartmentId implements Serializable {
private Long employeeId;
private Long departmentId;
// Default constructor
public EmployeeDepartmentId() {}
// Parameterized constructor
public EmployeeDepartmentId(Long employeeId, Long depar
tmentId) {
[Link] = employeeId;
[Link] = departmentId;
}
Hibernate 96
[Link] = departmentId;
}
@Override
public int hashCode() {
return [Link](employeeId, departmentId);
}
}
import [Link].*;
@Entity
@Table(name = "employee_department")
public class EmployeeDepartment {
@EmbeddedId
private EmployeeDepartmentId id;
Hibernate 97
}
Hibernate 98
-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
</dependencies>
property>
<property name="hibernate.c3p0.idle_test_period">30
00</property>
Hibernate 99
<!-- Specify dialect -->
<property name="[Link]">[Link]
alect.MySQL8Dialect</property>
</session-factory>
</hibernate-configuration>
import [Link].*;
@Entity
@Table(name = "employee_department")
public class EmployeeDepartment {
@EmbeddedId
private EmployeeDepartmentId id;
Hibernate 100
// Getters and setters
public EmployeeDepartmentId getId() {
return id;
}
Creating an EmployeeDepartment
Reading an EmployeeDepartment
Hibernate 101
public EmployeeDepartment getEmployeeDepartmentById(Session
session, Long employeeId, Long departmentId) {
EmployeeDepartmentId id =
Updating an EmployeeDepartment
Deleting an EmployeeDepartment
Hibernate 102
[Link]();
}
import [Link];
import [Link];
import [Link];
import [Link];
// Verify deletion
EmployeeDepartment deletedEmployeeDepartment = getE
mployeeDepartmentById(session, 1L, 1L);
if (deletedEmployeeDepartment == null) {
[Link]("Employee department success
fully deleted");
}
[Link]();
[Link]();
}
Hibernate 104
();
EmployeeDepartmentId id = new EmployeeDepartmentId
(employeeId, departmentId);
EmployeeDepartment employeeDepartment = [Link]
([Link], id);
if (employeeDepartment != null) {
[Link](role);
[Link](employeeDepartment);
}
[Link]();
}
14.5 Conclusion
Composite primary keys in Hibernate provide a robust way to handle complex
key structures involving multiple columns. By using annotations like
and , developers can easily define and manage composite keys,
ensuring the uniqueness and integrity of their data. The provided examples
demonstrate how to implement and test composite primary keys effectively.
Hibernate 105
Chapter 15: Introduction to Transaction
Management
15.1 Introduction to Transaction Management
Transaction management is a fundamental concept in any database-related
application. In Hibernate, transaction management ensures that a group of
operations are executed in a secure and reliable manner, maintaining data
consistency and integrity. Transactions in Hibernate can be managed
programmatically or declaratively using various frameworks like JTA or Spring.
15.2.1 Atomicity
Atomicity ensures that a series of operations within a transaction are treated as
a single unit. Either all operations succeed, or none of them do. This property
prevents partial updates to the database, which could lead to data
inconsistency.
15.2.2 Consistency
Consistency ensures that a transaction transforms the database from one valid
state to another valid state. After a transaction completes, all data integrity
constraints must be satisfied. This means that any given transaction will bring
the database from one valid state to another, maintaining database rules.
15.2.3 Isolation
Isolation ensures that the operations within a transaction are isolated from the
operations in other transactions. This prevents data anomalies due to
concurrent transactions. The isolation level determines the degree to which the
operations in one transaction are isolated from those in other transactions.
15.2.4 Durability
Durability ensures that once a transaction has been committed, it remains
committed even in the case of a system failure. This means that the data
Hibernate 106
changes made by the transaction are permanently saved in the database.
Solution
Use a higher isolation level like READ_COMMITTED or above to prevent dirty reads.
Hibernate default is .
Solution
Use the isolation level to ensure that once a row is read, it
cannot be modified by other transactions until the first transaction completes.
Solution
Use the isolation level to prevent phantom reads, which ensures
complete isolation from other transactions.
Hibernate 107
15.4 Types of Transactions
In Hibernate, transactions can be managed in several ways, including
programmatically using Hibernate API, JTA (Java Transaction API), and CMT
(Container Managed Transactions).
Example
Example
import [Link];
import [Link];
import [Link];
Hibernate 108
try {
[Link]();
// Perform database operations
[Link]();
} catch (Exception e) {
[Link]();
[Link]();
}
@Stateless
public class EmployeeService {
@PersistenceContext
private EntityManager entityManager;
@Service
@Transactional
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
Hibernate 109
public void createEmployee(Employee employee) {
[Link](employee);
}
15.5 Conclusion
Transaction management is crucial for maintaining data integrity and
consistency in any application. Understanding and correctly implementing the
ACID properties, addressing concurrency issues, and choosing the appropriate
type of transaction management are essential skills for developers working with
Hibernate. By leveraging programmatic transactions, JTA, and CMT, developers
can ensure robust transaction handling in their applications.
Hibernate 110
interface, which encapsulates the JDBC connection and transaction
management.
Example:
import [Link];
import [Link];
import [Link];
import [Link];
// Create a SessionFactory
SessionFactory sessionFactory = [Link]
SessionFactory();
// Open a session
Session session = [Link]();
// Begin a transaction
Transaction transaction = [Link]
();
try {
// Perform some database operations
MyEntity entity = new MyEntity();
[Link]("Example Name");
[Link](entity);
Hibernate 111
if (transaction != null) {
[Link]();
}
[Link]();
} finally {
// Close the session
[Link]();
}
Details:
Example:
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
Hibernate 112
public static void main(String[] args) {
try {
// Obtain the JTA UserTransaction
InitialContext context = new InitialContext();
UserTransaction userTransaction = (UserTransact
ion) [Link]("java:comp/UserTransaction");
// Create a SessionFactory
SessionFactory sessionFactory = configuration.b
uildSessionFactory();
// Open a session
Session session = [Link]();
Hibernate 113
n
[Link]();
try {
[Link]();
} catch (Exception rollbackException) {
[Link]();
}
}
}
}
Details:
Example:
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Stateless
@TransactionManagement([Link])
public class CMTTransactionExample {
@PersistenceContext
Hibernate 114
private EntityManager entityManager;
Details:
EntityManager: The JPA interface used for interacting with the persistence
context.
Summary:
Hibernate 115
interaction between the application and the database. is a thread-
safe, immutable object created once during application initialization and used to
create multiple objects.
Key Characteristics:
Example:
import [Link];
import [Link];
static {
try {
// Create the SessionFactory from [Link]
[Link]
sessionFactory = new Configuration().configure
().buildSessionFactory();
} catch (Throwable ex) {
// Log the exception as it might be swallowed
[Link]("Initial SessionFactory crea
tion failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
Hibernate 116
Details:
file.
Configuration: Configures Hibernate using the
2. Persistent State:
An object is in the persistent state if it is associated with an active Hibernate
and is synchronized with the database. Hibernate manages the object's
lifecycle and any changes made to it will be reflected in the database when the
transaction is committed.
3. Detached State:
An object is in the detached state if it was once persistent but its
has been closed. The object is no longer managed by Hibernate, and
changes made to it will not be automatically synchronized with the database
unless it is reattached to a new .
Hibernate 117
Session session = [Link]();
[Link]();
MyEntity entity = new MyEntity();
[Link]("Detached State");
[Link](entity);
[Link]().commit();
[Link]();
// Detached state
[Link]("Updated Detached State");
// Transient state
MyEntity entity = new MyEntity();
[Link]("Transient State");
// Persistent state
Session session = [Link]();
Hibernate 118
[Link]();
[Link](entity);
[Link]().commit();
[Link]();
// Detached state
[Link]("Updated Detached State");
Summary
In this chapter, we explored the , the backbone of Hibernate,
responsible for creating instances. We also delved into the different
Hibernate 119
performance.
1. First-Level Cache (Session Cache):
Example:
[Link]().commit();
[Link]();
2. Second-Level Cache:
Example Configuration:
To enable the second-level cache, you need to configure it in the Hibernate
configuration file (
) and specify a caching provider (e.g., Ehcache).
Hibernate 120
<!-- [Link] -->
<hibernate-configuration>
<session-factory>
<!-- Other configurations -->
Example Usage:
Hibernate 121
[Link]().commit();
[Link]();
Behavior: Each session maintains its own cache. Objects loaded during a
session are stored in this cache and are cleared when the session is closed.
2. Second-Level Cache:
3. Query Cache:
Configuration:
<property name="[Link].use_query_cache">true</p
roperty>
Example Usage:
Hibernate 122
[Link]().commit();
[Link]();
Summary
In this chapter, we explored the two main types of Hibernate cache: the first-
level cache, which is session-specific and enabled by default, and the second-
level cache, which is shared across sessions and needs to be explicitly
configured. We also touched on the query cache, an optional cache for caching
query results. Understanding and configuring these caching mechanisms can
significantly enhance the performance of your Hibernate applications by
reducing the load on the database.
Hibernate 123