Hibernate ленивая загрузка не работает

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

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

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

В моем unit test, Assertnull терпит неудачу, потому что getParent() не является нулевым

assertNull( folderTbl.getParent() );

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

Ответ 1

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

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

Ответ 2

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

Hibernate будет загружать объект при вызове метода getParent(), когда запрос на фактический объект будет загружен.

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

Ответ 3

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

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;
  }

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

Ответ 4

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

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

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

Ответ 5

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

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