Ответ
Hibernate использует прокси-объекты для реализации ленивой загрузки (Lazy Loading) ассоциаций. Это ключевая оптимизация для уменьшения количества запросов к БД и объема передаваемых данных.
Как это работает?
- При загрузке основной сущности (например,
User) связанная сущность (например,Address) с настройкойFetchType.LAZYне загружается сразу. - Вместо нее Hibernate подставляет прокси — динамически сгенерированный подкласс, который выглядит как
Address. - Фактическая загрузка данных из БД происходит при первом обращении к любому методу прокси (кроме
getId(), если доступен по ключу).
Пример:
@Entity
public class User {
@Id
private Long id;
@ManyToOne(fetch = FetchType.LAZY) // Указание на ленивую загрузку
private Address address; // На этом этапе будет прокси
}
// В коде
User user = session.find(User.class, 1L); // SELECT для User
Address addr = user.getAddress(); // Получаем прокси, запроса к БД НЕТ
String city = addr.getCity(); // ЗДЕСЬ выполняется SELECT для Address
Важное ограничение: Для инициализации прокси требуется активная сессия Hibernate (или контекст persistence в JPA). Попытка доступа к прокси после ее закрытия вызовет LazyInitializationException.