Обновившись до Spring Boot 3.3.0 (конкретно до Hibernate 6.5), мы столкнулись со 100% загрузкой процессора на БД из-за небольшого изменения в SQL коде, сгенерированного Hibernate после преобразования JPQL в SQL.
Посмотрите на следующий JPQL-запрос и обратите внимание на различия в генерации SQL для Hibernate 6.4 и Hibernate 6.5 при передаче пустого списка в качестве параметра.
interface ArticleRepository extends CrudRepository<Article, UUID> { @Query("from Article where publisherId in :ids") List<Article> findByPublisherId(List<UUID> ids); } var articles = articleRepository.findByPublisherId(List.of());
Hibernate 6.4.X:
select a1_0.id, a1_0.publisher_id, a1_0.title from article a1_0 where 1=0
Hibernate 6.5.X:
select a1_0.id, a1_0.publisher_id, a1_0.title from article a1_0 where (1 = case when a1_0.publisher_id is not null then 0 end)
Может показаться, что разница незначительная, однако в PostgreSQL первый запрос выполняется практически мгновенно, а второй приводит к полному сканированию таблицы (full table scan).
Стоит отметить, что при использовании derived-query вместо @Query с JPQL запрос будет отличаться:
interface ArticleRepository extends CrudRepository<Article, UUID> { List<Article> findByPublisherId(List<UUID> ids); } var articles = articleRepository.findByPublisherId(List.of());
select a1_0.id, a1_0.publisher_id, a1_0.title from article a1_0 where a1_0.publisher_id in (?)
Команда Hibernate уже поправила этот баг: https://github.com/hibernate/hibernate-orm/pull/8528
Осталось дождаться включения этого фикса в модуль Spring Data JPA.
Присоединяйтесь к русскоязычному сообществу разработчиков на Spring Boot в телеграм — Spring АйО, чтобы быть в курсе последних новостей из мира разработки на Spring Boot и всего, что с ним связано.
Ждем всех, присоединяйтесь!
ссылка на оригинал статьи https://habr.com/ru/articles/820175/
Добавить комментарий