Ответ 1
Прокси - это классы, динамически генерируемые Hibernate для обеспечения ленивой загрузки. Например, если у вас есть класс Cat
, Hibernate будет генерировать прокси-класс, который расширяет Cat
.
Если вы получите неинициализированный экземпляр этого прокси-сервера, по сути, все его поля будут пустыми, кроме ID, потому что Hibernate еще не попал в базу данных. Теперь, когда вы впервые вызовете метод на этом прокси, он поймет, что он не инициализирован, и он будет запрашивать базу данных для загрузки ее атрибутов. Это возможно, потому что динамически сгенерированный класс переопределяет методы базового класса и добавляет эту инициализированную/неинициализированную проверку.
Теперь предположим, что ваш класс Cat
не является прокси-сервером и что он имеет ассоциацию father
, когда вы загружаете объект Cat, Hibernate должен будет загрузить все его атрибуты. Поэтому, если вы загружаете объект Cat
, Hibernate также должен будет загрузить своего отца и отца-отца и так далее. Использование прокси позволяет Hibernate загружать только нужные экземпляры.
Cat cat1 = (Cat) session.load(1);
Cat cat2 = (Cat) session.load(2);
Cat cat3 = (Cat) session.load(3);
cat1.meow(); // this will cause Hibernate to run a query to load cat1 data
cat2.meow(); // this will cause Hibernate to run a query to load cat2 data
// After this cat3 is still an uninitiated proxy because it has not been used
batch-size
- еще одна особенность Hibernate, которая в большинстве случаев помогает справляться с ленивой загрузкой. В основном идея заключается в том, что Hibernate отслеживает неинициализированные прокси, и когда один из них нужно инициализировать, будет выполнен один запрос для загрузки до batch-size
прокси (вместо одного прокси-запроса)
Cat cat1 = (Cat) session.load(1);
Cat cat2 = (Cat) session.load(2);
cat1.meow(); // if batch-size >= 2, cat1 and cat2 will be loaded in a single query
cat2.meow(); // no query will be executed here