Tag Archives: ORM

Object-Relational Mapping — technique to map Java objects to relational database tables

The Hibernate 7 Persistence Context: How Hibernate Tracks Your Entities (and Where It Gets Surprising)

Look at this Spring service. Eight lines, nothing exotic, no annotations missing as far as a junior reviewer can tell. Before reading on, predict what happens when something calls markActive(42) against a real database.

@Service
public class UserService {
    private final UserRepository userRepo;
    public UserService(UserRepository r) { this.userRepo = r; }

    public User markActive(Long id) {
        User u = userRepo.findById(id).orElseThrow();
        u.setStatus("ACTIVE");
        return u;
    }
}

If you said “an UPDATE statement fires”, you would be wrong. There is no @Transactional on the method, so Spring Data opens a session for the duration of findById, returns the entity, and closes the session. By the time u.setStatus("ACTIVE") runs, u is no longer managed. The mutation exists only in JVM memory. There is no flush, no dirty check, no UPDATE.

This is the kind of bug you can stare at for an hour, because the code is almost right. It would be right if Hibernate worked the way most people imagine it does. The actual mechanics are stranger and more interesting — and once you see them, a long list of mysterious behaviours suddenly make sense: phantom UPDATEs, missing UPDATEs, NonUniqueObjectException, LazyInitializationException, the JPQL query that fires SQL you didn’t expect.

This post is a deep-dive on the persistence context: the in-memory state machine that decides what gets written, when, and why.

Continue reading The Hibernate 7 Persistence Context: How Hibernate Tracks Your Entities (and Where It Gets Surprising)

Bootstrapping EntityManager in Hibernate 7 (Jakarta Persistence 3.2) – XML vs Programmatic Guide

Are you struggling to bridge the gap between your Java objects and your relational database in the modern Jakarta EE era? If you’ve ever felt buried under boilerplate JDBC code or confused by the transition to Hibernate 7, you aren’t alone.

In modern Java development, bootstrapping EntityManager in Hibernate 7 is the foundational step for any robust data persistence layer. Hibernate 7 has fully embraced Jakarta Persistence 3.2, bringing stricter standards, better performance, and a move toward Java 17+ features. This version marks a significant milestone in the decoupling of Hibernate-specific logic from standard JPA interfaces.

TL;DR

  • 🚀 Requirements: Java 17+ and Jakarta Persistence 3.2 (complete jakarta.* namespace transition).
  • 🏗️ Architecture: EntityManagerFactory (EMF) is a thread-safe singleton; EntityManager (EM) is for short-lived units of work.
  • ⚙️ Configuration: Use XML (persistence.xml) for stability; use Programmatic (PersistenceConfiguration) for cloud-native/dynamic environments.
  • ⚠️ Critical Warning: Never create a new EntityManagerFactory per request. It leads to catastrophic Metaspace OOM errors.

The Problem: The Complexity of Manual Data Handling

Managing database connections manually is a developer’s nightmare. From opening connections and handling SQL exceptions to mapping result sets back into Java objects, the “traditional” JDBC way is error-prone and tedious. Without a properly bootstrapped EntityManager, your application lacks a unified way to manage entity lifecycles, leading to:

  • Memory Leaks: Connections that are never returned to the pool.
  • Data Inconsistency: Transactions that aren’t properly synchronized across operations.
  • Performance Bottlenecks: The infamous “N+1” query issues that arise when manual fetching isn’t optimized.
Continue reading Bootstrapping EntityManager in Hibernate 7 (Jakarta Persistence 3.2) – XML vs Programmatic Guide

Bootstrapping Hibernate 7: SessionFactory vs EntityManagerFactory vs Spring Boot Auto-Config — A Decision Guide

Most Spring Boot developers would struggle to answer the question: which Hibernate bootstrap path are you actually using? The answer is “the one Spring Boot chose for you”, which is the EntityManagerFactory path, built by HibernateJpaAutoConfiguration, wired to a HikariDataSource, reading from application.properties. You have never typed a single line of Hibernate bootstrap code.

That is fine for the common case. But when something breaks at startup — the wrong dialect is selected, HikariCP sizing is wrong, the schema validation fails — you need to know what is actually being configured and where. And for projects outside Spring Boot (command-line tools, framework libraries, Jakarta EE deployments), you need to choose a bootstrap path and implement it deliberately.

This post covers all three paths, when each makes sense, and the production failure that catches developers who autoconfig their way to production without understanding what they built.

Continue reading Bootstrapping Hibernate 7: SessionFactory vs EntityManagerFactory vs Spring Boot Auto-Config — A Decision Guide

Hibernate 7 Hello World: A Working Project from Empty Folder to First Insert

Most Hibernate Hello World tutorials get you to a running INSERT in about 10 minutes. They also leave out three things that will bite you the moment you move past the trivial case.

First: the import packages. Hibernate 7 requires jakarta.persistence.*, not javax.persistence.*. Every tutorial written before 2022 uses the old namespace. If you copy the entity annotation from a pre-Hibernate 6 guide, the annotations will not be recognised and you will spend 30 minutes wondering why your table never appears.

Second: the persistence.xml location trap in Maven multi-module setups. The file belongs at src/main/resources/META-INF/persistence.xml in the module that contains your entity classes. Putting it in the wrong module produces a silent failure at bootstrap.

Third: the LazyInitializationException you will hit in your second example. The first example always works because you access everything inside one open session. The second example accesses an association after the session closes. This post calls that out explicitly so you see it coming.

Everything else is the standard step-by-step: Maven setup, entity, configuration, utility class, first insert. The code is complete and runs without modification on Java 17+.

Three Things This Guide Gets Right That Most Hello World Tutorials Skip

Hibernate 7 is not just a minor update; it’s optimized for modern environments like Jakarta EE 11 and Java 17/21/25+. It leverages the latest features of the JPA (Jakarta Persistence API) to provide a more type-safe and performant way to interact with your data.

High-Level Architecture Overview

Understanding the flow of data is crucial for mastering any ORM. Here is the architectural stack for this tutorial:

Java ApplicationHibernate SessionJPA Entity ManagerDialectDatabase (H2/MySQL)

Continue reading Hibernate 7 Hello World: A Working Project from Empty Folder to First Insert

Dozer Bean Mapping in Java: Practical Guide with Benchmark vs MapStruct

In modern Java applications — particularly those built on Spring Boot or Jakarta EE — moving data between object models is a daily reality. You have DTOs (Data Transfer Objects) arriving from REST APIs and you need to convert them into Domain Entities for persistence, or vice versa. Writing manual getter-setter copy code for every field is tedious, error-prone, and buries your business logic under a mountain of boilerplate that grows with every new field added to your model.

Enter Dozer — a robust, open-source Java Bean mapper that recursively copies data from one object to another using reflection. Dozer has been a production staple for over a decade. While compile-time alternatives like MapStruct have gained popularity for performance-critical applications, Dozer remains a compelling choice for its runtime flexibility, zero build-plugin setup, and its ability to handle complex mapping scenarios without annotation proliferation on your model classes.

In this guide, we will cover practical Dozer usage from basic field mapping through nested objects, custom converters, and Spring integration — then benchmark Dozer against MapStruct so you can make an informed architectural decision for your next project.

Continue reading Dozer Bean Mapping in Java: Practical Guide with Benchmark vs MapStruct

Solved: Bean property ‘configurationClass’ is not writable or has an invalid setter method

Every developer has those moments where a seemingly simple task turns into a head-scratching puzzle. This error, encountered while trying to configure a custom LocalSessionFactoryBean in Spring Boot, is a perfect example of a subtle type mismatch causing a cryptic failure.


The Scenario and the Error

The goal was to set up a custom SessionFactory bean using Spring’s LocalSessionFactoryBean. The initial, problematic configuration was:

@Configuration
public class HibernateConfig {
    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        // … set data source, hibernate properties …
        
        // This line caused the error!
        sessionFactory.setConfigurationClass(org.hibernate.cfg.Configuration.class); 
        
        return sessionFactory;
    }
}

This configuration resulted in the following exception upon application startup:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': 
Bean property 'configurationClass' is not writable or has an invalid setter method. 
Does the parameter type of the setter match the return type of the getter?
Continue reading Solved: Bean property ‘configurationClass’ is not writable or has an invalid setter method

Solved: java.lang.NoClassDefFoundError: org/hibernate/cache/CacheProvider

Encountering a java.lang.NoClassDefFoundError can be one of the most frustrating issues when working with Java applications. This particular error — org/hibernate/cache/CacheProvider — is a common stumbling block for developers upgrading or mixing Hibernate versions. Let’s break down what it means and how to fix it.

Understanding the Error

The NoClassDefFoundError occurs when the JVM tries to load a class by its fully qualified name but cannot find its definition at runtime — even though the class existed at compile time. In this case, org.hibernate.cache.CacheProvider was the standard interface for Hibernate second-level cache integration in Hibernate 3.x. It was deprecated in Hibernate 4 and completely removed in Hibernate 5+, replaced by org.hibernate.cache.spi.RegionFactory.

Continue reading Solved: java.lang.NoClassDefFoundError: org/hibernate/cache/CacheProvider