Почему Hibernate.isPropertyInitialized возвращает true? - PullRequest
0 голосов
/ 09 ноября 2019

У меня есть класс Person, у которого есть отложенная коллекция с именем autos. После извлечения человека из базы данных я вызвал два спящих метода с именами isInitialized (autos) и isPropertyInitialized (personObject, autos), первый показывает false, второй показывает true. почему?

@Entity
public class Person {

    @OneToMany(mappedBy="person",fetch=FetchType.LAZY)
    private List<Auto> autos;

}


@Entity
public class Auto {

    @ManyToOne
    @JoinColumn(name = "person_id", nullable = false)
    private Person person;

}

Тестовый код:

Person p = personRepository.findAll().get(0);     
System.out.println(Hibernate.isInitialized(p.getAutos()));
System.out.println(Hibernate.isPropertyInitialized(p,"autos"));

Консоль:

false
true

1 Ответ

1 голос
/ 12 ноября 2019

Я считаю, что в этом случае использование 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...