Hibernate 5.6 to 6.x: Major Changes and Migration Tips

Date: November 20 2023


Hibernate ORM, one of the most popular Java persistence frameworks, made significant leaps moving from version 5.6 to 6.x. These changes reflect modern Java standards, better integration with Jakarta EE, improved type-safe querying, and cleaner APIs.

If you’re planning to migrate your application or just want to understand what’s new, this post will guide you through the major changes with concrete examples and tips.


1. Jakarta Namespace Migration

What Changed?

Hibernate 6 fully embraces Jakarta Persistence API (JPA) 3.0, which means all javax.persistence packages have moved to jakarta.persistence.

This requires updating your imports throughout the codebase.

Migration Tip:

  • Change all imports from:
  import javax.persistence.Entity;

to:

  import jakarta.persistence.Entity;
  • Your persistence.xml should also reference Jakarta namespaces.

Example:

// Hibernate 5.x
import javax.persistence.Entity;

@Entity
public class User {
    @Id
    private Long id;
    private String username;
}
// Hibernate 6.x
import jakarta.persistence.Entity;

@Entity
public class User {
    @Id
    private Long id;
    private String username;
}

2. New Type-safe Querying with the Hibernate ORM Query Language (HQL)

Hibernate 6 introduces a more type-safe query API to replace the old string-based HQL queries, reducing runtime errors.

Example: Traditional HQL in Hibernate 5.6

String hql = "FROM User WHERE username = :username";
List<User> users = session.createQuery(hql, User.class)
                          .setParameter("username", "johndoe")
                          .list();

Hibernate 6.x Typed Query API

List<User> users = session.createQuery(
    session.getCriteriaBuilder()
           .createQuery(User.class)
           .where(session.getCriteriaBuilder().equal(
               session.getCriteriaBuilder().literal("username"), "johndoe"
           ))
).list();

More idiomatic usage leverages the Criteria API enhancements for type safety:

CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> root = cq.from(User.class);

cq.select(root).where(cb.equal(root.get("username"), "johndoe"));

List<User> users = session.createQuery(cq).getResultList();

3. Simplified Configuration

Hibernate 6 simplifies its configuration APIs:

Before (Hibernate 5.6):

Configuration config = new Configuration();
config.configure("hibernate.cfg.xml");
SessionFactory sessionFactory = config.buildSessionFactory();

Now (Hibernate 6.x):

StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
    .configure("hibernate.cfg.xml")
    .build();

Metadata metadata = new MetadataSources(registry).getMetadataBuilder().build();
SessionFactory sessionFactory = metadata.getSessionFactoryBuilder().build();

The new Metadata and MetadataSources APIs improve bootstrapping flexibility.


4. Improved Collection Mappings

Hibernate 6 introduces new collection types for better handling of lists, maps, and sets with more control over ordering and sorting.

Example: Using @OrderColumn for ordered lists

@Entity
public class Book {
    @OneToMany
    @OrderColumn(name = "chapter_order")
    private List<Chapter> chapters;
}

Hibernate 6 improves the management of @OrderColumn and collection types so that changes in order are automatically detected and persisted.


5. New Session API and Improved Mutability Control

The Session interface has been enhanced with better support for mutability and state transitions:

Example: Evicting vs. Detaching

  • evict(entity) removes the entity from the session cache but keeps it persistent.
  • detach(entity) fully detaches the entity.

Hibernate 6 clarifies these semantics with improved methods to reduce bugs in state management.


6. Legacy APIs Removed

Some deprecated features have been removed:

  • The old Hibernate XML mappings (hbm.xml) have fewer supported features — annotation-based mappings are recommended.
  • Certain legacy Criteria APIs are removed in favor of the JPA Criteria API.

7. Migration Tips Summary

Migration AspectRecommendation
Namespace ChangeUpdate imports from javax to jakarta
QueryingPrefer JPA Criteria API over HQL strings
ConfigurationUse MetadataSources & SessionFactoryBuilder APIs
MappingsReview collection mappings and ordering
Remove Deprecated APIsReplace legacy Criteria and XML mappings
Test ThoroughlyRun integration tests and review cache behavior

8. Practical Migration Example

Before (Hibernate 5.6):

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Person {
    @Id
    private Long id;
    private String name;

    // getters/setters
}

// HQL query example
List<Person> persons = session.createQuery("from Person where name=:name", Person.class)
    .setParameter("name", "Alice")
    .list();

After (Hibernate 6.x):

import jakarta.persistence.Entity;
import jakarta.persistence.Id;

@Entity
public class Person {
    @Id
    private Long id;
    private String name;

    // getters/setters
}

CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
Root<Person> root = cq.from(Person.class);

cq.select(root).where(cb.equal(root.get("name"), "Alice"));

List<Person> persons = session.createQuery(cq).getResultList();

9. Conclusion

Migrating from Hibernate 5.6 to 6.x involves some upfront effort, particularly around namespace changes and adopting the improved query APIs. However, the benefits are clear:

  • Cleaner, type-safe queries that reduce runtime errors
  • Full Jakarta EE 9+ compatibility
  • Improved configuration and mapping flexibility
  • Better support for modern Java idioms

If you maintain an enterprise app or library using Hibernate, start planning your migration soon. Testing and incremental upgrades are key to a smooth transition.


Would you like me to help with sample migration guides, code snippets for legacy queries conversion, or tips on using Hibernate 6 features like multitenancy or caching? Just say the word!


Next up: Using Jakarta Persistence API (JPA) 3.0 in Modern Java Apps — stay tuned!

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *