惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

M
MIT News - Artificial intelligence
有赞技术团队
有赞技术团队
S
Schneier on Security
aimingoo的专栏
aimingoo的专栏
T
Troy Hunt's Blog
U
Unit 42
Hacker News - Newest:
Hacker News - Newest: "LLM"
V2EX - 技术
V2EX - 技术
T
The Blog of Author Tim Ferriss
V
Visual Studio Blog
H
Heimdal Security Blog
H
Hacker News: Front Page
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Cloudbric
Cloudbric
Google DeepMind News
Google DeepMind News
C
Cisco Blogs
The Cloudflare Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
MyScale Blog
MyScale Blog
F
Fortinet All Blogs
N
News | PayPal Newsroom
Attack and Defense Labs
Attack and Defense Labs
D
DataBreaches.Net
N
News and Events Feed by Topic
Security Archives - TechRepublic
Security Archives - TechRepublic
Forbes - Security
Forbes - Security
Simon Willison's Weblog
Simon Willison's Weblog
F
Full Disclosure
The Register - Security
The Register - Security
L
LINUX DO - 热门话题
Webroot Blog
Webroot Blog
Google Online Security Blog
Google Online Security Blog
AI
AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
Intezer
S
Security Affairs
阮一峰的网络日志
阮一峰的网络日志
K
Kaspersky official blog
云风的 BLOG
云风的 BLOG
博客园 - 叶小钗
T
Threatpost
Spread Privacy
Spread Privacy
小众软件
小众软件
AWS News Blog
AWS News Blog
S
Secure Thoughts
S
Security @ Cisco Blogs
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
J
Java Code Geeks

IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog

What’s fixed in IntelliJ IDEA 2026.2 - The JetBrains Blog Java Annotated Monthly – July 2026  - The JetBrains Blog IntelliJ IDEA 2026.1.4 Is Out! - The JetBrains Blog Kotlin Notebook Sunset - The JetBrains Blog Open-Sourcing the LSP Client API in IntelliJ IDEA 2026.2 - The JetBrains Blog Your JetBrains IDE Expertise, Now on LinkedIn - The JetBrains Blog Java Annotated Monthly – June 2026  | The IntelliJ IDEA Blog IntelliJ IDEA 2026.1.3 Is Out! | The IntelliJ IDEA Blog IntelliJ IDEA 2025.3.6 Is Out! | The IntelliJ IDEA Blog IntelliJ IDEA 2026.2 EAP Is Open | The IntelliJ IDEA Blog Improving Accessibility in JetBrains IDEs: What’s New and What’s Next in 2026 | The JetBrains Platform Blog IntelliJ IDEA 2026.1.2 Is Out! | The IntelliJ IDEA Blog 将 Spring Data JDBC 与 Kotlin 搭配使用 | The IntelliJ IDEA Blog IntelliJ IDEA 2025.3.5 is Out! | The IntelliJ IDEA Blog Java Annotated Monthly – May 2026 | The IntelliJ IDEA Blog Teaching an AI Agent to Debug Flaky Tests | The IntelliJ IDEA Blog 将 Spring Data JPA 与 Kotlin 搭配使用 | The IntelliJ IDEA Blog 如何避免使用 JPA 和 Kotlin 时的常见陷阱 | The IntelliJ IDEA Blog IntelliJ IDEA 2026.1.1 Is Out! | The IntelliJ IDEA Blog Using Spring Data JDBC With Kotlin | The IntelliJ IDEA Blog Java Annotated Monthly – April 2026 | The IntelliJ IDEA Blog Using Spring Data JPA with Kotlin | The IntelliJ IDEA Blog AI-Assisted Java Application Development with Agent Skills | The IntelliJ IDEA Blog IntelliJ IDEA 2026.1 Is Out! | The IntelliJ IDEA Blog What’s fixed in IntelliJ IDEA 2026.1 | The IntelliJ IDEA Blog Core JavaScript and TypeScript Features Become Free in IntelliJ IDEA | The IntelliJ IDEA Blog IntelliJ IDEA's New Kotlin Coroutine Inspections, Explained | The IntelliJ IDEA Blog IntelliJ IDEA 2025.3.4 is Out! | The IntelliJ IDEA Blog Java 26 in IntelliJ IDEA | The IntelliJ IDEA Blog Koog Comes to Java: The Enterprise AI Agent Framework From JetBrains | The JetBrains AI Blog Sunsetting Code With Me | The JetBrains Platform Blog
Hibernate 7.4 New Features | The IntelliJ IDEA Blog
Siva Katamreddy · 2026-05-29 · via IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
Idea logo

IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin

Java

Hibernate 7.4 New Features

Hibernate 7.4 introduced several improvements that simplify loading a page of data along with their associated child collection, historical data access, and audit logging.

The article will focus on the following features:

  • Limits and Fetch Joins: How Hibernate 7.4 improves working with paginated queries that include fetched associations.
  • History and Audit Tables: How the new capabilities support querying entity state across time and working with historical data.


You can check out the sample code for this article in this GitHub repository.

Limits and Fetch Joins

One common requirement in data-driven applications is loading a page of parent entities along with an associated child entity collection. For example, suppose an application has an Order entity with a Set<OrderItem> collection, and we want to load the first few orders together with their order items.

List<Order> orders = session
        .createSelectionQuery(
            "select o from Order o join fetch o.items order by o.id",
            Order.class
        )
        .setMaxResults(10)
        .getResultList();

In Hibernate versions before 7.4, applying a limit to a query that used a collection fetch join could not be safely pushed down to the database. Because each Order may have multiple OrderItem rows, limiting the SQL result directly could cut off part of an order’s item collection. To avoid returning incomplete collections, Hibernate loaded all matching rows from the database and applied pagination in memory at the application layer.

That behavior was correct, but it could be expensive. A query intended to load only 10 orders might still read many more rows if the table contained a large number of orders and order items.

Before Hibernate 7.4, the generated SQL would look like the following:

select
    o1_0.id, i1_0.order_id, i1_0.id, i1_0.product_code,
    i1_0.quantity, o1_0.order_number, o1_0.status
from
    orders o1_0
        join
    order_items i1_0
    on o1_0.id=i1_0.order_id

As you can see, the limit(pagination) is not applied at the SQL query level. So, it will load all the orders and their associated order_items, which could be a very expensive operation and may result in OutOfMemoryException.

You can see a WARNING logged by Hibernate as follows:

[WARN] HHH90003004: firstResult/maxResults specified with collection fetch; applying in memory

One option to prevent Hibernate performing pagination in memory is by setting the following property:

hibernate.query.fail_on_pagination_over_collection_fetch=true

By configuring this property, Hibernate throws an exception instead of performing pagination in memory.

Hibernate 7.4 fixes this problem by using nested queries. Instead of applying the limit directly to the joined result set, Hibernate first determines the limited set of parent entity identifiers and then fetches the associated collection for only those parent rows. 

This allows pagination to happen in the database while still returning complete items collections for each selected Order.

With Hibernate 7.4, the SQL will be generated as follows:

select
        o1_0.id, i1_0.order_id, i1_0.id, i1_0.product_code,
        i1_0.quantity, o1_0.order_number,o1_0.status 
    from
        (select
            o1_0.id, o1_0.order_number, o1_0.status 
        from
            orders o1_0 
        where
            exists(select
                1 from order_items i1_0 
            where
                o1_0.id=i1_0.order_id) 
        offset
            ? rows 
        fetch
            first ? rows only) o1_0(id, order_number, status) 
    join
        order_items i1_0 
            on o1_0.id=i1_0.order_id

This improvement makes fetch joins more practical for paginated screens, such as an order listing page that displays each order with its line items, without forcing the application to load the full result set first.

History and Audit Tables

Hibernate 7.4 adds built-in support for temporal history tables and audit tables. Both features help track changes to entity data, but they serve slightly different use cases: history tables let us query the state of an entity at a point in time, while audit tables record the sequence of changes that happened to an entity.

Consider the following Product entity:

@Entity
@Table(name = "products")
class Product {
    //fields id, code, name, price
}

History Tables

To enable temporal history for Product, annotate the entity with @Temporal and optionally specify the history table name using @Temporal.HistoryTable.

@Entity
@Table(name = "products")
@Temporal
@Temporal.HistoryTable(name="products_history")
class Product {
    //fields id, code, name, price
}

With this mapping, Hibernate stores previous versions of product rows in the products_history table. The table includes the entity columns plus two temporal columns: effective, which marks when a version became active, and superseded, which marks when that version was replaced.

products_history table:

idcodenamepriceeffectivesuperseded
2251P1000Product-100040.002026-05-15 08:21:39.949001 +00:00null
2301P1001Product-100190.002026-05-15 08:22:24.765883 +00:002026-05-15 08:22:24.778067 +00:00
2301P1001Product-1001100.002026-05-15 08:22:24.778067 +00:00null

We can get the Product entity data at a given point of time as follows:

Instant someTime = ...
try (var session = sessionFactory.withOptions().asOf(someTime).open()) {
    var product = session.find(Product.class, productId);
    
}

This makes temporal queries feel like normal entity lookups while Hibernate resolves the correct historical row behind the scenes.

Hibernate offers several different strategies(NATIVE, SINGLE_TABLE, HISTORY_TABLE) for mapping temporal entities. For more info check out the Temporal data section.

Audit Tables

Previously, Hibernate-based applications typically used the separate Hibernate Envers library for auditing entity changes. Hibernate 7.4 brings audit table support into Hibernate ORM itself, so applications can use auditing features natively without adding Envers for this use case.

Audit support is enabled by adding @Audited and can be mapped to a custom table using @Audited.Table.

@Entity
@Table(name = "products")
@Audited
@Audited.Table(name="products_aud_log")
class Product {
    //fields id, code, name, price
}

When auditing is enabled, Hibernate writes one row per change into the audit table. Unlike the history table, the audit table focuses on recording what operation happened and when.

idcodenamepricerevrevtype
2001P1002Product-100290.002026-05-13 14:58:17.505775 +00:000
2001P1002Product-1002100.002026-05-13 14:58:17.518194 +00:001

The rev values are the timestamps at which the change happened. The revtype values are represented using ModificationType enum as follows:

public enum ModificationType {
    /**
    * Creation, encoded as 0
    */
    ADD,
    /**
    * Modification, encoded as 1
    */
    MOD,
    /**
    * Deletion, encoded as 2
    */
    DEL
}

For more info check out the Audit logs section.

Summary

Most of the applications use pagination to show a list of resources, and we used to write custom logic to load paginated data along with the associated child collection. Now this is being handled at the framework level itself. Also, we used to rely on external libraries like Envers to implement auditing, which is now provided by Hibernate itself.

Hibernate 7.4 brings practical improvements that address real problems in JPA/ Hibernate-based applications. Whether we are optimizing pagination query behavior or tracking historical data, Hibernate 7.4 reduces the amount of custom infrastructure needed and provides better support out of the box without requiring additional libraries.

Go ahead and explore these new features using this GitHub repository.

Subscribe to IntelliJ IDEA Blog updates

Discover more