JPA: подводный камень с @ElementCollection и fetch = FetchType.EAGER… — Библиотека Java разработчика — TG.ME

🧠 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 — он не так прост, как кажется.

📲 Мы в MAX

👉@BookJava
👍1
July 31, 2026 967 9