# Review No. 8

Published 2023-06-10

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 ?

  1. 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).

  1. 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).

# 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 !

# 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:

  1. you call the entityManager.persist method;
  2. you find an entity from the database (using fetch() method);
  3. you merge/update a detached entity by calling the entityManager.merge or entityManager.update method
  • Detached state : was previously managed but is no longer attached to the current JPA Persistence Context.

An entity goes to a Detached state when:

  1. you call the entityManager.detach method;
  2. 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).

# 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.

# 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
  • 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.

TypedQuery example
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.

NamedQuery example
@Entity
@NamedQuery(name = "Employee.findByDepartment",
            query = "FROM Employee e WHERE e.department.id = :deptId")
public class Employee {
    // class implementation
}
NamedQuery example
// 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).