#
Review No. 8
This page contains Java (Hibernates) concepts briefly explained.
#
What is Jakarta EE specification ?
Jakarta EE specification is the new name of Java EE, after Java EE was transferred to the Eclipse Foundation ( from 2019). Spring Boot 3 is based on Spring Framework 6.0 and Jakarta EE 9. Starting from Hibernate 6, Jakarta EE is used.
#
How can we use a composite PK with Hibernate/ JPA ?
- using
@IdClass
annotation:
@Entity
@IdClass(BookId.class)
public class Book {
@Id
private String title;
@Id
private String language;
// other fields, getters and setters
}
In this example BookId class implements Serializable, has no annotation and has 2 fields (title & language).
- using
@EmbeddedId
annotation:
@Entity
public class Book {
@EmbeddedId
private BookId bookId;
// constructors, other fields, getters and setters
}
In this case BookId class implements Serializable, is annotated with @Embeddable and has 2 fields (title & language).
Info
The entity class must be public and must have a public no-arg constructor.
#
What is persistence.xml used for in Hibernate ?
persistence.xml describes the persistence units. A persistence unit contains all we need for creating a connection to the database (database URL, jdbc driver, username, password, etc).
For the same database we can have many persistence units.
The Entity Manager is created by a Entity Manager Factory (which use the information provided by a "persistence unit").
#
Where are the transactions created in Hibernate ?
The transactions are created by an Entity Manager.
#
What is an Entity Manager ?
An Entity Manager is an object which manage the Persistence Context and has a connection to the database.
#
What is Persistence Context ?
The Persistence Context (which is also the 1st level cache) is the place where the entities are automatically managed (by an EntityManager). commit() or flush() methods are used for the entities we have in the Persistence Context only !
Info
// Create a new User entity instance
User user = new User("john_doe", "john.doe@example.com");
// Persist the User entity
// em = EntityManager
em.persist(user);
When an entity is created it is not created in the Persistence Context. This entity is in the NEW (TRANSIENT) state. You need to "persist" the entity in order to put the entity in the Persistence Context (the new state become MANAGED or PERSISTENT).
In general, we have one Persistence Context per transaction and we have on EntityManager per Persistence Context.
#
Which are the entity states in Hibernate ?
New (Transient)
state : the entity is created but not associated with JPA Persistence Context (Hibernate session). The association is done calling entityManager.persist(entity) method.Managed/Persistent
state : any changes made to objects in this state are automatically propagated to database when the commit is done.
An entity goes to a Managed/Persistent state when:
- you call the entityManager.persist method;
- you find an entity from the database (using fetch() method);
- you merge/update a detached entity by calling the entityManager.merge or entityManager.update method
Info
- update method expects not to have the same instance in the JPA Persistence Context (Hibernate session) (where the entity is moved). We receive an error if we have such an instance in JPA Persistence Context.
Detached
state : was previously managed but is no longer attached to the current JPA Persistence Context.
An entity goes to a Detached state when:
- you call the entityManager.detach method;
- when the Persistence Context is closed;
Removed
state : the entity is marked for DELETE using the entityManager.remove method (the entity is in the Persistence Context).
Info
The save() method is an "original" Hibernate method that doesn't conform to the JPA specification. Its purpose is basically the same as persist, but there are some different implementation details.
#
Which transaction-types can we use with Hibernate ?
transaction-type="RESOURCE_LOCAL"
-> we don't have distributed transactions (the transactions are managed in the application : you must create the EntityManagerFactory and then get the EntityManager).transaction-type="JTA"
-> when RESOURCE_LOCAL is not what we want (EntityManager supplied by the container).
#
flush() vs commit() methods
- flush() -> send the command to DB (needed when we work with large amount of data)
- commit() -> send the "commit" command to the DB (data is persisted permanently)
#
refresh() method
refresh() method overwrites any changes made to an entity instance in the Hibernate session. This is useful when database triggers are used to update some properties of the object or when the ID (Primary Key) is set on the database level.
Info
An entity instance is associated with a row in the database.
#
save() method
The save() method is an "original/old" Hibernate method that doesn't conform to the JPA specification.
#
Deprecated methods in Hibernate 6
save(), update(), saveOrUpdate()
#
Physical vs Logical Transactions in Spring
- Physical Transactions - what we actually have on the database.
- Logical Transactions - we can have "nested" logical transaction into one physical transaction.
#
@Entity(name = "N1") vs @Table(name = "N2")
- N1 - the name of the Entity, used in Queries
- N2 - the name of the table in the database (DB)
#
Which are the Query types we can have in Hibernate ?
- JPQL (Java Persistence Query Language) - This is part of JPA and is similar to HQL.
- HQL (Hibernate Query Language) - extends the JPQL with new functionalities (Hibernate specific). HQL is a subset of JPQL.
- Criteria API - deprecated from Hibernate 5.2.
- JPA Criteria API - it is a part of JPA, and it is standardized for use across different ORM providers
Info
Using Criteria API (JPA or not) you cannot see the Query, but you can build (easily) dynamic queries.
- SQL (Native Queries) - are standard SQL queries that are executed directly against the database. The SELECT, UPDATE, etc are database specific and the Persistence Context is not used.
#
Which are the HQL features not found in JPQL ?
- JOIN FETCH option could be used to eagerly load the information from the joined tables
- we can use specific Hibernates function in Query. For instance, the "elements" function:
WHERE 'Java' IN elements(e.skills)
- more flexibility in subqueries
- supports SQL hints
#
What TypedQuery is in Hibernates ?
We are using TypedQuery when the type of the result is defined in the code => type safe.
Session session = sessionFactory.openSession();
TypedQuery<Employee> query = session.createQuery("FROM Employee WHERE salary > :minSalary", Employee.class);
query.setParameter("minSalary", 30000);
List<Employee> employees = query.getResultList();
session.close();
#
What NamedQuery is in Hibernates ?
Named queries are predefined queries that are used by referencing their names.
@Entity
@NamedQuery(name = "Employee.findByDepartment",
query = "FROM Employee e WHERE e.department.id = :deptId")
public class Employee {
// class implementation
}
// Example of using a named query to fetch employees by department
Session session = sessionFactory.openSession();
Query<Employee> query = session.createNamedQuery("Employee.findByDepartment", Employee.class);
query.setParameter("deptId", 10);
List<Employee> employees = query.getResultList();
session.close();
#
Which are the Cache Levels in Hibernates ?
- 1st Level Cache (persistence context) : enabled by default, keeps the entities Hibernates works with. This is at the session level.
- 2nd Level Cache (application cache) : it is disabled by default. For using it we can use providers like Ehcache, Infinispan, and Hazelcast.
- Query Cache : when we cache the result of a query (requires the second-level cache to be enabled).
#
What evict() method is doing in Hibernates ?
evict(entity) method removes the specified entity from the first-level cache (persistence context). It does the same thing as detach() method (which runs evict() method under the hood).
#
@Cachable vs @Cache
- @Cacheable : (Spring specific) to keep in cache the result of a method (related to a database operations or not).
- @Cache : (Hibernate specific) tells how to configure the 2nd Level Cache.
#
spring-boot-starter-data-jpa vs spring-data-jpa
spring-boot-starter-data-jpa contains spring-data-jpa + the necessary dependencies to set up a JPA environment easily (Hibernetes, HikariCP, auto-configuration, etc).