Java.Hibernate.Beginner.What is query cache in Hibernate?

The query cache in Hibernate is an optional, second-level caching mechanism that stores the results of HQL or Criteria queries, so that the same query with the same parameters can return results without re-executing the SQL against the database.

🔹 How it works:

  • When query caching is enabled:
    1️⃣ You mark a query as cacheable (per-query).
    2️⃣ The first time you run the query, Hibernate executes it against the database, stores the result IDs in the query cache, and caches the entities in the second-level cache.
    3️⃣ On subsequent identical queries (same HQL and parameters), Hibernate fetches the result directly from the query cache → no SQL sent.

🔹 Example usage:

List<User> users = session.createQuery("FROM User WHERE active = true", User.class)
                          .setCacheable(true)
                          .list();

🔹 In this example:
✅ The first call executes the SQL and caches the result.
✅ Later identical calls reuse the cached result list (IDs of matching rows) + second-level cached entities.

🔹 Important points:

  • Query cache doesn’t cache entity data itself — it only caches IDs of query results.
  • Actual entity data must be in the second-level cache for query cache hits to be fully effective.
  • Query cache is best used for read-heavy, rarely changing queries, like reference data, menus, or lookup tables.

🔹 How to enable globally in configuration:

hibernate.cache.use_query_cache=true

🔹 When not to use it:

  • For frequently updated data, because invalidating the cache can cause more overhead than benefit.
  • For dynamic queries with constantly changing parameters, as they won’t benefit from caching.

✅ Key takeaway:
Hibernate’s query cache stores query results (IDs) so repeated identical queries avoid hitting the database, but requires second-level cache to cache actual entities for full benefit.

Posted in Без рубрики | Comments Off on Java.Hibernate.Beginner.What is query cache in Hibernate?

Java.Hibernate.Beginner.Does sessionFactory lives in sessionManager ?

Not quite — there isn’t actually a Hibernate class called SessionManager. But let’s unpack the correct relationship between these components:


🔹 SessionFactory:

  • The SessionFactory is the central, heavyweight Hibernate component.
  • It’s created once per application (singleton) and is thread-safe.
  • It holds configuration (database settings, mappings, cache regions) and produces individual Session instances as needed.
  • Think of it as a factory: its job is to create and manage Sessions, but it doesn’t itself contain or manage active sessions.

🔹 Session:

  • Each Session is a lightweight, per-unit-of-work object created by the SessionFactory.
  • The Session manages:
    • Database connections,
    • First-level cache,
    • Transaction boundaries.

🔹 What about Spring’s Transaction Manager?

  • In Spring, you typically don’t work with SessionFactory and Session directly.
  • Instead, Spring uses a transaction manager like HibernateTransactionManager or JpaTransactionManager to:
    • Acquire a Session from the SessionFactory when a transaction begins,
    • Bind that Session to the current thread,
    • Commit or rollback the transaction,
    • Close the Session automatically.
  • So you could think of Spring’s transaction manager as the “manager” coordinating SessionFactory and Sessions, but there’s no Hibernate class literally called SessionManager.

🔹 Diagram of relationships:

[SessionFactory] 
     ↳ creates → [Session] ← managed by → [Spring Transaction Manager (@Transactional)]

✅ Key takeaway:

  • SessionFactory doesn’t “live” inside any SessionManager.
  • Instead, SessionFactory exists independently and produces Session instances.
  • In Spring apps, the transaction manager orchestrates the lifecycle of sessions created by the SessionFactory.
Posted in Без рубрики | Comments Off on Java.Hibernate.Beginner.Does sessionFactory lives in sessionManager ?

Java.Hibernate.Beginner.Do i need openSession in SpringBoot ?

No, you almost never need to manually call openSession() in a typical Spring Boot application. Spring Boot, through Spring Data JPA or Spring’s @Transactional support, manages the Hibernate session lifecycle automatically for you.


🔹 How it works in Spring Boot:

  • When you annotate a method or class with @Transactional, Spring opens a Hibernate session behind the scenes, binds it to the current thread, and manages:
    • Starting a transaction,
    • Flushing changes,
    • Committing or rolling back the transaction,
    • Closing the session automatically when your method finishes.
  • For example:
@Service
public class UserService {
    @Transactional
    public void updateUsername(Long id, String newName) {
        User user = entityManager.find(User.class, id); // Hibernate session is already active here
        user.setUsername(newName);                      // changes tracked
        // session flush/commit handled automatically at method exit
    }
}

✅ No need for sessionFactory.openSession(), beginTransaction(), commit(), or close() — Spring Boot handles it transparently.

🔹 How is this possible?

  • Spring Boot configures a JpaTransactionManager (or HibernateTransactionManager) that creates and manages the Hibernate session based on your @Transactional boundaries.
  • Sessions are usually scoped to the transaction — so each @Transactional method gets its own session.

🔹 When might you manually open a session?

  • Rare advanced scenarios, like:
    • Using a StatelessSession for bulk operations.
    • Writing a custom repository implementation requiring low-level Hibernate features.
    • Managing multiple sessions explicitly (multi-tenancy, special batch processes).

But 99% of the time, you should let Spring manage it, especially in CRUD or business service layers.


✅ Key takeaway:
In Spring Boot apps, you don’t need to manually open or close Hibernate sessions — simply use @Transactional, and Spring will handle session management, transaction boundaries, and resource cleanup automatically.

Posted in Без рубрики | Comments Off on Java.Hibernate.Beginner.Do i need openSession in SpringBoot ?

Java.Hibernate.Beginner.Session lifecycle

✅ Hibernate Session Lifecycle


🔹 1) Open

  • You open a new Session from a SessionFactory:
Session session = sessionFactory.openSession();

A new first-level cache is created, and the session is ready to interact with the database.

🔹 2) Begin Transaction (optional but recommended)

  • Start a database transaction associated with the session:
Transaction tx = session.beginTransaction();

🔹 3) Perform Operations

  • Perform CRUD operations inside the session:
User user = new User();
user.setUsername("john");
session.save(user); // entity becomes persistent in the session cache

User fetched = session.get(User.class, user.getId()); // served from cache or DB
fetched.setEmail("john@example.com"); // change is tracked automatically

🔹 4) Flush (automatic or manual)

  • Hibernate flushes pending changes in the session cache to the database, generating SQL statements.
  • This happens automatically:
    • Before committing the transaction.
    • Or manually if you call session.flush().

🔹 5) Commit or Rollback Transaction

  • Commit writes the changes permanently:
tx.commit();

Or rollback discards the changes if an error occurs:

tx.rollback();

🔹 6) Close Session

  • Releases JDBC connections and destroys the first-level cache:
session.close();

🔹 Lifecycle summary diagram:

openSession() → beginTransaction() → [CRUD] → flush → commit/rollback → closeSession()

✅ Important points:

  • Session is lightweight but not thread-safe → use one session per unit of work (e.g., per request).
  • While the session is open, Hibernate tracks changes to persistent entities and caches them in first-level cache.
  • Closing the session releases resources and evicts the first-level cache.

🔹 Example full lifecycle:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

User user = session.get(User.class, 1L); // fetch or load entity
user.setUsername("newName");            // modification tracked

tx.commit();                            // flush + commit
session.close();                        // releases resources

✅ Key takeaway:
The session lifecycle spans opening → transaction → CRUD → flush → commit/rollback → close, and understanding it is critical to writing efficient, bug-free Hibernate code.

Posted in Без рубрики | Comments Off on Java.Hibernate.Beginner.Session lifecycle

Java.Hibernate.Beginner.What is second-level cache in Hibernate?

The second-level cache (2nd-level cache) is an optional, shared Hibernate cache that stores entities (and sometimes collections) beyond the scope of a single session — allowing data to be reused across multiple sessions in the same application, which can dramatically improve performance.


🔹 Key characteristics:
✅ Unlike the first-level cache (session-scoped, mandatory), second-level cache is session factory-scoped and optional.
✅ Stores entity data in memory or distributed caches (e.g., Ehcache, Infinispan, Redis).
✅ When enabled, Hibernate first checks the second-level cache before querying the database for an entity.
✅ Helps reduce database load by serving frequently accessed data from cache, especially in read-heavy applications.

🔹 How it works:

  • When you load an entity in Hibernate, if second-level cache is enabled:
    1. Hibernate first checks the first-level cache (session).
    2. If not found, it checks the second-level cache (shared across sessions).
    3. If still not found, it queries the database, then stores the result in both caches.
  • This flow allows multiple sessions (and even different application nodes) to reuse cached data.

🔹 Basic example of enabling second-level cache with Ehcache:
hibernate.cfg.xml

<hibernate-configuration>
  <session-factory>
    ...
    <property name="hibernate.cache.use_second_level_cache">true</property>
    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
  </session-factory>
</hibernate-configuration>

Entity class:

@Entity
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class User {
    @Id
    private Long id;
    private String username;
}

🔹 Common second-level cache providers:

  • Ehcache (most widely used)
  • Infinispan
  • Redis (via plugins)
  • OSCache

🔹 What can be cached:
✅ Entities
✅ Collections (e.g., lists, sets in one-to-many mappings)
✅ Query results (using query cache)

✅ Key takeaway:
Second-level cache is a shared, optional cache in Hibernate that stores entities beyond individual sessions, reducing database load and improving performance for repeated reads of frequently used data.

Posted in Без рубрики | Comments Off on Java.Hibernate.Beginner.What is second-level cache in Hibernate?

Java.Hibernate.Beginner.What is first-level cache in Hibernate?

The first-level cache is Hibernate’s mandatory, built-in caching mechanism that automatically stores persistent entities within the scope of a single Hibernate Session.

🔹 Key characteristics:
✅ Enabled by default — you cannot disable it.
✅ Scoped to a single Session — each session has its own first-level cache.
✅ Stores entities you load, save, or update during the session.
✅ Avoids repeated database queries: if you fetch the same entity multiple times in one session, Hibernate serves it from the cache instead of querying the database again.
✅ Automatically synchronizes changes: Hibernate tracks any modifications to cached entities and updates the database on flush() or commit().

🔹 Example showing first-level cache in action:

Session session = sessionFactory.openSession();
session.beginTransaction();

User user1 = session.get(User.class, 1L); // SQL query sent to DB
User user2 = session.get(User.class, 1L); // NO SQL sent — served from first-level cache!

System.out.println(user1 == user2); // true — same object instance

session.getTransaction().commit();
session.close();

🔹 When is the cache cleared?

  • When you call session.clear() → explicitly evicts all cached entities.
  • When you call session.evict(entity) → evicts a specific entity.
  • When the session is closed → cache is destroyed.

🔹 Why it matters:

  • Improves performance by minimizing redundant database queries.
  • Ensures consistency within a session: all reads of the same entity return the same in-memory object.

✅ Key takeaway:
The first-level cache is session-scoped, automatic, and essential for Hibernate’s performance and correctness — it ensures efficient data access and consistent object identity within a session.

What happens if data changed in database and i get them from cache ? what if i always need fresh data ?

🔹 If you load an entity into the session (which caches it) and then someone else changes the data directly in the database (e.g., another app or SQL query), your current session’s first-level cache won’t see the change:

  • Any further calls like session.get() for the same entity ID will return the cached entity, not a fresh copy from the database.
  • This can lead to stale data in your app.

🔹 Example of stale data:

Session session = sessionFactory.openSession();
session.beginTransaction();

User user = session.get(User.class, 1L); // fetches from DB
// Someone else updates user with ID=1 directly in the database...

User sameUser = session.get(User.class, 1L); // served from first-level cache — still shows old data!

session.getTransaction().commit();
session.close();

✅ How to get fresh data inside the same session?
1️⃣ Use session.refresh(entity) → forces Hibernate to re-fetch the entity from the database and update the cached object.

session.refresh(user); // overwrites the cached user with fresh data from DB

2️⃣ Alternatively, you could evict the entity from the session’s cache:

session.evict(user);                     // remove from first-level cache
User freshUser = session.get(User.class, 1L); // triggers new SQL query to DB

✅ What if you always need fresh data?

  • First-level cache cannot be disabled; it’s mandatory in Hibernate.
  • But you can:
    • Open a new session for every operation requiring fresh data.
    • Call session.refresh() explicitly for entities where consistency is critical.
    • Use stateless sessions (StatelessSession) for read-only operations needing fully fresh data — but you lose features like automatic dirty checking, cascading, etc.

Session session = sessionFactory.openSession();
session.beginTransaction();

while (true) {
    // Suppose we want to read updated data every 5 seconds
    User user = session.get(User.class, 1L);

    // Force Hibernate to bypass first-level cache and reload fresh data from DB
    session.refresh(user);

    System.out.println("Latest username: " + user.getUsername());

    try {
        Thread.sleep(5000); // wait 5 seconds
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}

session.getTransaction().commit();
session.close();

🔹 Important note:

  • First-level cache only affects your own session — if your app needs real-time data accuracy across users, you must combine database-level features (e.g., optimistic locking) or use second-level cache invalidation strategies.

✅ Key takeaway:
First-level cache improves performance by avoiding redundant queries, but it can lead to stale reads if external changes occur. Use session.refresh() or evict/reload entities when you absolutely need fresh data.

Posted in Без рубрики | Comments Off on Java.Hibernate.Beginner.What is first-level cache in Hibernate?

Java.Hibernate.Beginner.How do you map a Java class to a database table in Hibernate?

You can map a Java class to a database table in Hibernate in two main ways:


🔹 1) Using JPA annotations (modern, recommended)
Add annotations directly to your Java class:

import javax.persistence.*;

@Entity                    // Marks the class as a persistent entity
@Table(name = "users")     // Maps the class to the 'users' table
public class User {

    @Id                    // Marks this field as the primary key
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "username") // Maps 'username' field to 'username' column
    private String username;

    @Column(name = "email")    // Maps 'email' field to 'email' column
    private String email;

    // getters and setters
}

✅ With annotations:

  • @Entity: tells Hibernate this class should be persisted.
  • @Table: specifies the table name (optional if it matches class name).
  • @Id: defines the primary key.
  • @Column: customizes the column name, type, etc.

🔹 2) Using XML mapping files (older approach)
Create an XML file (e.g., User.hbm.xml):

<!DOCTYPE hibernate-mapping PUBLIC
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="com.example.User" table="users">
    <id name="id" column="id">
      <generator class="native"/>
    </id>
    <property name="username" column="username"/>
    <property name="email" column="email"/>
  </class>
</hibernate-mapping>

✅ In hibernate.cfg.xml, include the mapping:

<mapping resource="com/example/User.hbm.xml"/>

🔹 Key differences:

  • Annotations keep mappings close to your code (easier to read and maintain).
  • XML mappings let you change the mapping without modifying Java source code (useful for certain legacy or dynamic scenarios).

✅ Key takeaway:
You map a Java class to a database table in Hibernate by defining:

  • The class as an @Entity (or XML <class> element),
  • The table name with @Table or table="" in XML,
  • The fields with @Column or <property> in XML.
Posted in Без рубрики | Comments Off on Java.Hibernate.Beginner.How do you map a Java class to a database table in Hibernate?

Java.Hibernate.Beginner.When i say save, is it saved to cache ?

✅ When you call save() on an entity, does it save to the cache or the database?

Answer:
When you call session.save(entity) in Hibernate:

🔹 1) First, it saves the entity to the session’s first-level cache:

  • The entity becomes persistent: Hibernate starts tracking it.
  • The Session maintains an in-memory cache of persistent entities, called the first-level cache.
  • At this point, the entity’s state is not yet immediately written to the database.

🔹 2) Then, at flush() or transaction commit(), Hibernate writes changes to the database:

  • Hibernate will automatically generate SQL INSERT or UPDATE statements for all persistent entities with changes.
  • flush() synchronizes the session’s in-memory state with the database.

🔹 Example:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

User user = new User();
user.setUsername("john");

session.save(user); // user is now in the first-level cache, not yet in DB

// No SQL sent to DB yet, unless flush happens here

tx.commit(); // Hibernate flushes pending changes to DB (INSERT happens now)
session.close();

🔹 Key point about the first-level cache:

  • This cache is per-session: each Session has its own cache of entities it manages.
  • It’s mandatory in Hibernate — you cannot disable it.
  • It avoids repeated SQL queries or updates for the same entity during a session.

✅ So:

  • session.save() → adds the entity to the session’s first-level cache.
  • Only on flush or commit does Hibernate actually persist the entity’s state to the database.
Posted in Без рубрики | Comments Off on Java.Hibernate.Beginner.When i say save, is it saved to cache ?

Java.Hibernate.Beginner.Explain Enity lifecycle

Hibernate defines three states an entity can be in during its lifetime:

🔹 1) Transient

  • What it means: The object exists in Java memory but is not yet known to Hibernate, and not saved to the database.
  • Example:
User user = new User();         // new object in memory
user.setUsername("john");       // but not saved anywhere

If you don’t save it, it’s just a regular Java object with no connection to the DB.

🔹 2) Persistent

  • What it means: The object is associated with an open Hibernate session, and any changes to it are automatically tracked and synchronized with the database (e.g., on flush() or commit()).
  • Example:
Session session = sessionFactory.openSession();
session.beginTransaction();

User user = new User();
user.setUsername("john");
session.save(user);            // user is now persistent!

user.setEmail("john@example.com"); // Hibernate will notice this change
session.getTransaction().commit();
session.close();

While the session is open, any modifications are automatically saved to the database.

🔹 3) Detached

  • What it means: The object was persistent, but now the session is closed, or you manually evicted it — so Hibernate is no longer tracking it.
  • Example:
Session session = sessionFactory.openSession();
User user = session.get(User.class, 1L); // persistent
session.close();                         // session closed

user.setUsername("newName");  // user is now detached
// Hibernate won’t save this change automatically, because the session is gone.

To update changes in a detached object, you must reattach it with session.update() or session.merge().

🔹 Quick analogy:

  • Transient: A draft email you haven’t sent or saved yet.
  • Persistent: An email draft you’re editing in your email app — changes are saved live.
  • Detached: A saved draft you’ve closed; you can reopen it later, but changes won’t sync unless you explicitly save again.

✅ Key takeaway:

  • Transient → Not yet saved or tracked.
  • Persistent → Tracked by Hibernate in an open session.
  • Detached → Previously tracked, but the session ended — so changes are no longer auto-saved.
Posted in Без рубрики | Comments Off on Java.Hibernate.Beginner.Explain Enity lifecycle

Java.Hibernate.What is an entity in Hibernate?

✅ What is an entity in Hibernate?

Answer:
In Hibernate (and JPA), an entity is a lightweight, persistent Java object whose state is mapped to a table row in a relational database. Entities represent the domain model of your application and are the primary building blocks for Object-Relational Mapping.

🔹 Key points about entities:
✅ An entity must be a POJO (Plain Old Java Object).
✅ It must be annotated with @Entity (or mapped via XML in legacy Hibernate).
✅ It must have a field annotated with @Id to define the primary key.
✅ By default, the entity class name is mapped to a table with the same name — or you can customize it using @Table.

🔹 Basic example of a Hibernate entity:

import javax.persistence.*;

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "username")
    private String username;

    private String email;

    // Getters and setters
}

🔹 What makes an entity special:

  • Hibernate automatically tracks its state changes inside a session.
  • Changes to entities are synchronized with the database (e.g., on flush or transaction commit).
  • Supports features like lazy loading, cascading, and automatic SQL generation.

🔹 Entity lifecycle states:

  • Transient: Not associated with any Hibernate session.
  • Persistent: Associated with an open session and synchronized with the DB.
  • Detached: Was persistent but the session was closed or the object was evicted.

✅ Key takeaway:
An entity is a persistent Java object mapped to a database table row, central to ORM and Hibernate’s ability to manage your data automatically.

Posted in Без рубрики | Comments Off on Java.Hibernate.What is an entity in Hibernate?