@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

