Как работать с ленивой инициализацией? [LazyInitializationException] - PullRequest
0 голосов
/ 30 июня 2018

Чтобы получить ленивый объект, вам нужно вызвать Hibernate.initialize(proxy), например. в вашем классе обслуживания:

public <R> R fetchLazy(T entity, Function<T,R> proxyMapper) {
    entity = ensureEntityHasOpenedSession(entity);
    R proxy = proxyMapper.apply(entity);
    Hibernate.initialize(proxy);
    return proxy;
}

За пределами сферы обслуживания нужно было бы позвонить:

AnotherEntity another = service.fetchLazy(entity, Entity::getAnotherEntity);

Теперь вопрос, почему это работает:

another.getId();

при последующем вызове нет:

entity.getAnotherEntity().getId(); // LazyInitializationException

Не было AnotherEntity сохранено в Entity после первой выборки? Мне всегда нужно звонить

service.fetchLazy(entity, Entity::getAnotherEntity).getSomething(); 

Если это так, Hibernate.initialize(Object) возвращает кэшированный прокси при втором вызове или всегда есть другой доступ к базе данных (выполнение запроса)?

EDIT

Я использую аннотации JPA для полей частного класса в сочетании с lombok @ Getter @ Setter аннотациями.

Ответы [ 2 ]

0 голосов
/ 03 августа 2018

Проблема с последующим вызовом заключалась в реализации метода ensureEntityHasOpenedSession(entity) в сочетании с стратегией доступа , как указано @ChristianBeikov.

Чтобы быть более точным, я реализовал упомянутый метод как entityManager.find(entityClass, entityId), который возвращает новый экземпляр сущности . В результате, AnotherEntity прокси был инициализирован в новом экземпляре объекта, в то время как последующий вызов манипулировал со старым экземпляром объекта. Поскольку я использовал аннотации полей , любой вызов метода приводил к инициализации прокси, как указано в Шаблоны реализации JPA: доступ к полю и доступ к свойству :

Реализация отложенной загрузки Hibernate всегда инициализирует отложенную загрузку. прокси, когда любой метод на этом прокси вызывается. Единственное исключение для этот метод аннотируется @Id при использовании доступ к собственности. Но когда вы используете полевой доступ, такого метода нет и Hibernate инициализирует прокси даже при вызове метода, который возвращает личность объекта.

следовательно LazyInitializationException (старая сущность с закрытой сессией + пытается инициализировать прокси).

0 голосов
/ 19 июля 2018

Вы, вероятно, используете доступ к полям JPA, т. Е. Вы аннотировали поля Java ваших классов сущностей, а не получателей. Это известное ограничение доступа к полям в Hibernate. Единственный способ избежать исключения или явной инициализации - использовать вместо этого доступ к свойству.

Также см. Следующие проблемы JIRA для получения дополнительной информации

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