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

推荐订阅源

P
Privacy International News Feed
P
Palo Alto Networks Blog
Scott Helme
Scott Helme
Latest news
Latest news
Spread Privacy
Spread Privacy
WordPress大学
WordPress大学
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
CERT Recently Published Vulnerability Notes
P
Privacy & Cybersecurity Law Blog
Cyberwarzone
Cyberwarzone
博客园 - 三生石上(FineUI控件)
T
Tenable Blog
Security Latest
Security Latest
The Hacker News
The Hacker News
阮一峰的网络日志
阮一峰的网络日志
N
Netflix TechBlog - Medium
Project Zero
Project Zero
大猫的无限游戏
大猫的无限游戏
罗磊的独立博客
D
Darknet – Hacking Tools, Hacker News & Cyber Security
博客园 - 【当耐特】
C
Cybersecurity and Infrastructure Security Agency CISA
有赞技术团队
有赞技术团队
GbyAI
GbyAI
aimingoo的专栏
aimingoo的专栏
F
Fortinet All Blogs
Google DeepMind News
Google DeepMind News
A
Arctic Wolf
O
OpenAI News
Hugging Face - Blog
Hugging Face - Blog
G
Google Developers Blog
博客园_首页
V
V2EX
PCI Perspectives
PCI Perspectives
人人都是产品经理
人人都是产品经理
L
LINUX DO - 热门话题
I
InfoQ
爱范儿
爱范儿
C
Check Point Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
云风的 BLOG
云风的 BLOG
S
Secure Thoughts
The Last Watchdog
The Last Watchdog
Know Your Adversary
Know Your Adversary
S
Security Archives - TechRepublic
IT之家
IT之家
博客园 - 司徒正美
Last Week in AI
Last Week in AI
S
SegmentFault 最新的问题
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Новые возможности Hibernate 7.4
Spring АйО · 2026-06-16 · via Все публикации подряд на Хабре

Простой

5 мин

3

В Hibernate 7.4 появилось несколько улучшений упрощающих загрузку страницы данных вместе со связанными дочерними коллекциями, доступ к историческим данным и ведение журнала аудита.

В статье рассматриваются следующие возможности:

  • Limits и Fetch Joins: как Hibernate 7.4 улучшает работу с постраничными запросами, включающими загрузку ассоциаций.

  • History и Audit Tables: как новые возможности поддерживают запросы к состоянию сущности в разные моменты времени и работу с историческими данными.


Пример кода к этой статье доступен в репозитории GitHub.

Limits и Fetch Joins

Одна из типичных задач в приложениях, работающих с данными, — загрузить страницу родительских сущностей вместе со связанной коллекцией дочерних сущностей. Например, предположим, что в приложении есть сущность Order с коллекцией Set<OrderItem> , и нам нужно загрузить несколько первых заказов вместе с их позициями.

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

В версиях Hibernate до 7.4 применение ограничения к запросу с fetch join коллекции нельзя было безопасно передать на уровень базы данных. Поскольку каждый Order может содержать несколько строк OrderItem , прямое ограничение SQL-результата могло обрезать коллекцию позиций заказа. Чтобы избежать возврата неполных коллекций, Hibernate загружал все подходящие строки из базы данных и применял пагинацию в памяти на уровне приложения.

Такое поведение было корректным, но могло обходиться дорого. Запрос, рассчитанный на загрузку только 10 заказов, всё равно мог считывать значительно больше строк, если таблица содержала большое количество заказов и позиций.

До Hibernate 7.4 генерируемый SQL выглядел примерно так:

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

Как видно, ограничение (пагинация) не применяется на уровне SQL-запроса. Поэтому будут загружены все orders и связанные с ними order_items, что может оказаться очень затратной операцией и привести к OutOfMemoryException.

Hibernate при этом записывает в лог предупреждение следующего вида:

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

Один из способов запретить Hibernate выполнять пагинацию в памяти — задать следующее свойство:

hibernate.query.fail_on_pagination_over_collection_fetch=true

При установке этого свойства Hibernate будет выбрасывать исключение вместо того, чтобы выполнять пагинацию в памяти.

Hibernate 7.4 решает эту проблему с помощью вложенных запросов. Вместо того чтобы применять ограничение непосредственно к результату JOIN, Hibernate сначала определяет ограниченный набор идентификаторов родительских сущностей, а затем загружает связанную коллекцию только для этих строк.

Это позволяет выполнять пагинацию на стороне базы данных, при этом для каждого выбранного Order возвращаются полные коллекции позиций.

В Hibernate 7.4 SQL генерируется следующим образом:

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

Это улучшение делает fetch join по-настоящему удобным для постраничных экранов — например, страницы списка заказов, где каждый заказ отображается вместе со своими позициями, — без необходимости предварительно загружать весь результирующий набор.

History и Audit Tables

Hibernate 7.4 добавляет встроенную поддержку history tables и audit tables. Обе возможности позволяют отслеживать изменения данных сущностей, но решают немного разные задачи: history tables позволяют запрашивать состояние сущности в определённый момент времени, тогда как audit tables фиксируют последовательность и природу изменений, произошедших с сущностью.

Рассмотрим следующую сущность Product :

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

History Tables

Чтобы включить историю (т.е. history table) для Product, аннотируйте сущность с помощью @Temporal и при необходимости укажите имя таблицы истории с помощью @Temporal.HistoryTable.

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

При таком маппинге Hibernate сохраняет предыдущие версии строк продукта в таблице products_history . Таблица включает колонки сущности и две дополнительные колонки: effective, которая фиксирует момент активации версии, и superseded, которая фиксирует момент её замены.

products_history :

id

code

name

price

effective

superseded

2251

P1000

Product-1000

40.00

2026-05-15 08:21:39.949001 +00:00

null

2301

P1001

Product-1001

90.00

2026-05-15 08:22:24.765883 +00:00

2026-05-15 08:22:24.778067 +00:00

2301

P1001

Product-1001

100.00

2026-05-15 08:22:24.778067 +00:00

null

Данные сущности Product в заданный момент времени можно получить следующим образом:

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

Благодаря этому запросы состояния сущности в момент времени ‘t’ выглядят как обычный поиск сущностей, тогда как Hibernate самостоятельно разрешает нужную историческую строку за кулисами.

Hibernate предлагает несколько стратегий маппинга временны́х сущностей: NATIVE, SINGLE_TABLE и HISTORY_TABLE. Подробнее см. в разделе Temporal data.

Таблицы аудита

Раньше приложения на базе Hibernate, как правило, использовали отдельную библиотеку Hibernate Envers для аудита изменений сущностей. Hibernate 7.4 встраивает поддержку таблиц аудита непосредственно в Hibernate ORM, так что приложения могут использовать эту функциональность нативно — без подключения Envers для данного сценария.

Поддержка аудита включается добавлением @Audited и может быть привязана к произвольной таблице с помощью @Audited.Table.

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

При включённом аудите Hibernate записывает в таблицу аудита по одной строке на каждое изменение. В отличие от таблицы истории, таблица аудита ориентирована на фиксацию того, какая именно операция произошла (DELETE, UPDATE или INSERT) и когда именно.

id

code

name

price

rev

revtype

2001

P1002

Product-1002

90.00

2026-05-13 14:58:17.505775 +00:00

0

2001

P1002

Product-1002

100.00

2026-05-13 14:58:17.518194 +00:00

1

Значения rev — временны́е метки момента изменения. Значения revtype представлены с помощью ModificationType enum следующим образом:

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

Подробнее см. в разделе Audit logs.

Итоги

В большинстве приложений для отображения списков ресурсов используется пагинация, и раньше приходилось писать собственную логику для постраничной загрузки данных вместе со связанными дочерними коллекциями. Теперь это решается на уровне самого фреймворка. Кроме того, для реализации аудита мы привыкли опираться на внешние библиотеки, такие как Envers — теперь же эта возможность предоставляется самим Hibernate.

Hibernate 7.4 привносит практичные улучшения, решающие реальные задачи в приложениях на базе JPA/Hibernate. Будь то оптимизация поведения запросов при пагинации или отслеживание исторических данных — Hibernate 7.4 сокращает объём инфраструктурного кода, который нужно писать самостоятельно, и обеспечивает более богатую поддержку из коробки без необходимости подключать дополнительные библиотеки.

Изучите эти новые возможности на примере данного репозитория на GitHub.

Присоединяйтесь к русскоязычному сообществу разработчиков на Spring Boot в телеграм — Spring АйО, чтобы быть в курсе последних новостей из мира разработки на Spring Boot и всего, что с ним связано.