Я считаю, что в этом случае использование Hibernate.isPropertyInitialized
может быть неправильным.
В соответствии с документацией Hibernate.isPropertyInitialized
следует использовать для проверки лени для атрибутов или состояния, например "name"
для Person
объекта. Для проверки ленивости субъектов следует использовать Hibernate.isInitialized
boolean personInitialized = Hibernate.isInitialized(person);
boolean personBooksInitialized = Hibernate.isInitialized(person.getBooks());
boolean personNameInitialized = Hibernate.isPropertyInitialized(person, "name");
Или предпочтительно, как указано в документации javax.persistence.PersistenceUtil.isLoaded
PersistenceUtil persistenceUnitUtil = Persistence.getPersistenceUtil();
boolean personInitialized = persistenceUnitUtil.isLoaded(person);
boolean personBooksInitialized = persistenceUnitUtil.isLoaded(person.getBooks());
boolean personNameInitialized = persistenceUnitUtil.isLoaded(person, "name");
Теперь, почему существует Hibernate.isPropertyInitialized
и почему этовсегда возвращает true
Я полагаю, что основной причиной является улучшение байт-кода и отложенная загрузка атрибутов.
Обычно при извлечении объекта загружаются все атрибуты, например "name"
, "age"
и т. д.
При получении объекта также будут загружены все атрибуты. Это связано с тем, что каждый атрибут сущности неявно помечен аннотацией @Basic, для которой по умолчанию используется политика извлечения FetchType.EAGER. source
Однако с расширением Bytecode мы можем определить, какой из атрибутов должен быть ленивым. Это полезно, когда у нас есть несколько больших атрибутов, таких как blob image. Я считаю, что для этого конкретного сценария нам нужно Hibernate.isPropertyInitialized
Почему в вашем случае он всегда возвращает true
. Если мы посмотрим на Java Doc этого метода, то увидим, что он ожидает
@param proxy The potential proxy
Если это HibernateProxy
, то будет проверено, не инициализирован ли он. Если да, вы получите false
, поскольку для лени прокси все атрибуты инициализированы с нетерпением, таким образом, прокси не инициализирован, тогда атрибуты также. С другой стороны, у нас есть оператор
@return true if the named property of the object is not listed as uninitialized; false otherwise
Так что в вашем случае вы не используете ленивый механизм выборки атрибутов и не пропускаете прокси-объект, так как Person
уже инициализирован. Невозможно проверить, указано ли свойство как неинициализированное, поэтому возвращается true
.