Спящая ленивая загрузка не работает - PullRequest
11 голосов
/ 03 марта 2011

Я использую версию 3.6.1.Final

У меня есть следующее свойство в моем компоненте

    @JoinColumn( name = "FOLDER_PARENT_ID", referencedColumnName = "FOLDER_ID" )
@ManyToOne(cascade=CascadeType.MERGE, fetch= FetchType.LAZY )
private FolderTbl parent;

В моем модульном тесте Assertnull терпит неудачу, потому что getParent () не равен нулю

assertNull( folderTbl.getParent() );

Что еще мне нужно сделать, чтобы остановить спящий режим при загрузке родителя?

Ответы [ 5 ]

8 голосов
/ 03 марта 2011

Даже если для lazy установлено значение true, родительское значение не будет нулевым.Ленивая загрузка использует прокси-объект и присваивает его родительскому свойству.Когда мы пытаемся использовать родительский объект (вызов getParent()), он загружает фактический родительский объект с использованием прокси-объекта.

Если вы не хотите загружать объект, не настраивайте свойства JPA для элемента иустановите его как переходный.

7 голосов
/ 03 марта 2011

Родитель настроен правильно до загрузка лениво , дело в том, что вы неправильно его тестируете .

Hibernate загрузит объект, когда вы вызываете метод getParent(), когда приходит запрос к реальному объекту, он загрузится.

Вы можете проверить эту вещь, установив show_sql в true. он вызовет запрос, когда вы вызовете getParent()

1 голос
/ 20 июня 2012

Hibernate рассматривает Ленивое получение как подсказку.Вот что сказано в спецификации JPA 2.0 на стр. 364 Таблица 9.

(Необязательно) Должно ли значение поля или свойства загружаться лениво или его нужно извлекать с нетерпением.Стратегия EAGER - это требование времени выполнения поставщика постоянства, что значение должно быть извлечено с нетерпением.Стратегия LAZY - это подсказка для среды выполнения персистентного провайдера.

0 голосов
/ 03 марта 2011

На самом деле, вызов getParent () может вернуть экземпляр прокси, который покажет вам, что есть родитель. Если вы получите доступ к полям, отличным от идентификатора, родитель будет загружен в случае необходимости.

Обратите внимание, что родительский объект может быть уже загружен транзакцией и, таким образом, находиться в кэше первого уровня. Если это так, Hibernate обычно не будет делать другой запрос к базе данных.

Как было сказано ранее, если ваша сущность имеет непереходную ссылку на родительский элемент, getParent () всегда будет возвращать ненулевое значение, даже если сам родительский объект еще не загружен.

0 голосов
/ 03 марта 2011

В некоторых случаях вам может не понадобиться загружать отложенную коллекцию вообще.У вас может быть метод, подобный приведенному ниже, чтобы отсоединить коллекцию от сеанса.

public class. .... {
.....
  @JoinColumn( name = "FOLDER_PARENT_ID", referencedColumnName = "FOLDER_ID" )
  @ManyToOne(cascade=CascadeType.MERGE, fetch= FetchType.LAZY )
  private FolderTbl parent;
  ...
  public void detachLazyObjects() {
     parent = null;
  }

Затем вызовите этот метод, чтобы отсоединить класс от того места, где он должен быть нулевым.Пожалуйста, используйте этот ярлык экономно, я бы посоветовал вам подумать о других способах сделать это, прежде чем прибегнуть к этому решению.

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