🧠 JPA: подводный камень с @ElementCollection и fetch = FetchType.EAGER



Сегодня покажу, почему @ElementCollection(fetch = FetchType.EAGER) — скрытая угроза производительности и неожиданного поведения.

📌 Суть проблемы
При использовании @ElementCollection с EAGER Hibernate делает отдельный SELECT на каждую коллекцию, даже при JOIN FETCH на родительскую сущность.

@Entity
class User {
@Id Long id;

@ElementCollection(fetch = FetchType.EAGER)
List<String> tags;
}

Запрос findAll() приведёт к N+1 проблеме:
1 запрос на User, потом по одному на каждый tags.

💡 Почему это больно
Даже если вы используете JOIN FETCH на User, Hibernate не может сделать JOIN на @ElementCollection. Это ограничение — Hibernate всегда грузит коллекцию отдельным запросом.

⚠️ Особенно опасно при pagination
Если вы делаете Page<User> — Hibernate сначала грузит User'ов, а затем делает N запросов на коллекции. В проде это быстро становится проблемой.

✅ Что делать
1. Делайте fetch = FetchType.LAZY (по умолчанию так и есть).
2. Если нужно подгрузить коллекцию — используйте @BatchSize:

@ElementCollection
@BatchSize(size = 20)
List<String> tags;

Или вручную:

SELECT u FROM User u LEFT JOIN FETCH u.tags WHERE u.id IN :ids

👉 Следи за @ElementCollection — он не так прост, как кажется.

👉 @BookJava
Просмотры: 568
Открыть в MAX Сообщить о неточности

Репосты публикации

Публикация канала

Сообщить о неточности

Опишите, что нужно исправить. Если есть источник, добавьте ссылку.

Вы покидаете datool.ru

Ссылка ведёт на внешний сайт. datool.ru не отвечает за его содержимое — проверьте адрес, прежде чем вводить пароли или платёжные данные.

Переход через 10 с

Перейти