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 - это подсказка для времени выполнения провайдера.