Spring и Hibernate: как очищать тестовые данные без @DataJpaTest
Hibernate ORM 6.2 добавил SchemaManager: его метод truncateMappedObjects() очищает все таблицы, связанные с JPA-сущностями. В интеграционных тестах Spring очистку можно запускать в @BeforeEach, а затем заново добавлять исходные записи через TransactionTemplate.
Так тесты не приходится оборачивать в транзакцию @DataJpaTest. Иначе тестовый EntityManager остаётся доступен после вызова сервисного метода и может инициализировать ленивые прокси, хотя в рабочей среде они уже вызвали бы LazyInitializationException. Часть SQL-операторов также может не выполниться, а целостность базы останется непроверенной.
Очистка в начале теста надёжнее @AfterEach: при сбое или остановке в отладчике завершающий метод может не выполниться. В разборе Vlad Mihalcea есть полный пример с последовательными и параллельными переводами между счетами.
Как Hardwood ускоряет чтение фиксированных списков Parquet
Parquet кодирует координаты и векторные представления как списки переменной длины, даже если размер всегда одинаков. При чтении он разбирает признаки пустых значений и границы записей, выделяет массивы и собирает списки заново. Это примерно втрое медленнее плоской колонки.
Для готовящегося релиза Hardwood реализовали быстрый путь: читатель проверяет, что страница состоит из списков одной длины без пустых значений, и пропускает реконструкцию Dremel. В тесте с ZSTD списки из трёх элементов читались в 1,1 раза быстрее построчно и в 2,5 раза быстрее по колонкам. Для 768 элементов ускорение достигло 3,7 и 2,5 раза соответственно.
В разборе механизма показано, как байтовые шаблоны проверяются пачками и когда включается обычная обработка. Java Vector API оставили возможным следующим шагом, если эта проверка сама станет узким местом.
Как сборщики мусора JDK связывают память и производительность
JDK предлагает несколько сборщиков мусора с разными характеристиками. При этом у них есть общие архитектурные решения, которые отличают управление памятью в Java от сборки мусора в других языках. Материал объясняет, почему сборщики JDK устроены именно так и как их работа влияет на производительность приложений.
Отдельная тема: связь между объёмом RAM и нагрузкой на CPU бывает неочевидной, поэтому рассматривать эти ресурсы нужно вместе. Такой взгляд помогает обсуждать память Java не только через объём занятой RAM, но и через вычислительную цену выбранного подхода.
В материале Inside.java также разбирают спорный вопрос: действительно ли Java расходует слишком много памяти или другие языки используют её слишком мало. Полезная проверка предпосылок перед сравнением сборщиков мусора и профилей нагрузки.
Docker Compose с JDK 26: зависимости в контейнерах, Java локально
В примере Maven-приложение остаётся обычным локальным процессом, а Postgres 18 запускается через Docker Compose. Версия базы закреплена в docker-compose.yml, порт 5433 хоста связан с портом 5432 контейнера, поэтому JDBC подключается к localhost:5433.
Так команда получает одинаковую версию и конфигурацию базы после клонирования репозитория. Контейнер запускается командой docker compose up -d и удаляется через docker compose down, а Java-код можно отлаживать с обычными точками останова без пересборки образа.
В разборе Дэна Веги есть полный пример приложения закладок на JDK 26, Maven и JDBC, структура Compose-файла и команды для логов и консоли PostgreSQL.
Как перевести Dev Services на новый API Quarkus 3.25
В Quarkus 3.25 появился новый API для Dev Services. Старый механизм мог запускать сервисы для всех тестов ещё при обнаружении JUnit: в наборах с разными профилями это приводило к нескольким контейнерам, конфликтам портов и лишним расходам.
Теперь Quarkus подготавливает сервис при сборке, а запускает после аугментации, до старта приложения. Ядро сравнивает конфигурации, переиспользует экземпляры и управляет их жизненным циклом.
Авторам расширений предлагают перейти на owned() и discovered(), передавать сервис через Startable и убрать статические поля. Пользователям миграция не нужна.
Hibernate 7: как заменить устаревший @GenericGenerator
При миграции на Hibernate 7 аннотацию @GenericGenerator предлагают заменить метааннотацией @IdGeneratorType. Она связывает собственную аннотацию поля с классом генератора, после чего Hibernate создаёт идентификатор при сохранении сущности.
В статье Vlad Mihalcea разобраны два прежних сценария. Для идентификаторов TSID, отсортированных по времени, на поле id ставится @Tsid, связанная с TsidGenerator. Для оптимизатора последовательности pooled-lo используется @SequenceOptimizer. Обе готовые реализации есть в Hypersistence Utils.
Для enterprise-кодовой базы это практическая карта миграции: найти применения @GenericGenerator, разделить собственные генераторы и настройки последовательностей, затем перенести каждую группу на соответствующую аннотацию.
Как собрать движок отказоустойчивых сценариев на Java и SQLite
Persistasaurus показывает устройство движка, который сохраняет состояние многошагового Java-сценария. Метод с @Flow задаёт сценарий, методы с @Step обозначают сохраняемые шаги, а SQLite хранит их параметры, статусы и результаты.
После сбоя сценарий запускают с тем же UUID. Завершённые шаги получают результаты из журнала, а упавший шаг выполняется повторно. Так приложение не дублирует уже успешные операции, например дорогие и недетерминированные обращения к большим языковым моделям.
В разборе Gunnar Morling есть схема журнала и критерий для границ шага: сохранять стоит долгие, дорогие или трудно воспроизводимые операции. Это учебный прототип, а не готовый промышленный движок, но по нему удобно разобрать механику контрольных точек и восстановления Java-сервисов.