мы можем добиться ленивой выборки в методах get () и load () в Hibernate [duplicate]

Обозначение скобок позволяет вам получить доступ к свойствам по имени, хранящимся в переменной:

var obj = { "abc" : "hello" };
var x = "abc";
var y = obj[x];
console.log(y); //output - hello

obj.x не будет работать в этом случае.

84
задан tomato 4 March 2009 в 02:36
поделиться

8 ответов

Из форума Hibernate :

Это из книги Hibernate in Action. Хорошо прочитал это.


Извлечение объектов по идентификатору Следующий фрагмент кода гибернации извлекает объект пользователя из базы данных:

User user = (User) session.get(User.class, userID);

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

User user = (User) session.load(User.class, userID);

Метод load () старше; get () был добавлен в API Hibernate из-за запроса пользователя. Разница тривиальна:

Если load () не может найти объект в кеше или базе данных, генерируется исключение. Метод load () никогда не возвращает null. Метод get () возвращает null, если объект не может быть найден.

Метод load () может возвращать прокси вместо реального постоянного экземпляра. Прокси - это заполнитель, который запускает загрузку реального объекта при первом доступе; С другой стороны, get () никогда не возвращает прокси. Выбор между get () и load () прост: если вы уверены, что постоянный объект существует, а несуществование будет считаться исключительным, load () является хорошим вариантом. Если вы не уверены, что существует постоянный экземпляр с данным идентификатором, используйте get () и проверьте возвращаемое значение, чтобы узнать, является ли оно нулевым. Использование load () имеет еще одно значение: приложение может извлекать действительную ссылку (прокси) в постоянный экземпляр, не удаляя базу данных, чтобы получить ее постоянное состояние. Таким образом, load () не может генерировать исключение, если он не находит постоянный объект в кеше или базе данных; исключение будет выведено позже, когда прокси-сервер будет доступен. Конечно, извлечение объекта по идентификатору не так гибко, как использование произвольных запросов.

113
ответ дан Nandkumar Tekale 27 August 2018 в 23:14
поделиться
  • 1
    Я отлаживаю проблему прямо сейчас, когда session.Get & lt; T & gt; () возвращает прокси-сервер! – Kent Boogaart 29 March 2010 в 16:03
  • 2
    Большое спасибо! Денежная часть для меня была: & quot; Если load () не может найти объект в кеше или базе данных, генерируется исключение. Метод get () возвращает значение null, если объект не может быть найден. & Quot; – Chris 28 July 2010 в 05:23
  • 3
    JavaDoc для Session.get говорит: Возвращает постоянный экземпляр данного класса сущности с данным идентификатором или null, если такой постоянный экземпляр отсутствует. (Если экземпляр или прокси для экземпляра уже связан с сеансом, верните этот экземпляр или прокси.) Таким образом, раздел из книги, который гласит: «С другой стороны, get () никогда не возвращает прокси. ; не является правильным. – Vicky 7 May 2011 в 04:04
  • 4
    если вы используете стратегию управления транзакциями с помощью своих даос, вы можете предпочесть get (). в противном случае вызывающий должен также выполняться в контексте сеанса открытого спящего режима в случае, если load () возвращает прокси. например, если вы выполняете MVC, ваш контроллер может выполнить dao.load (), а затем выбросить исключение при попытке получить доступ к прокси-объекту позже, если нет действительного сеанса. doo.get () вернет фактический объект в контроллер независимо от сеанса (если он существует) – dev 4 April 2012 в 19:14
  • 5
    Проблема, описанная @Vicky, может вызвать головные боли, и я не вижу в этом никаких преимуществ. В некоторых случаях мне дополнительно нужен идентификатор для дальнейших параметризованных запросов. Но поскольку прокси-объект объекта уже находится в сеансе, то получатель идентификатора возвращает значение null. Почему они получают прокси вместо реального экземпляра, если этот прокси-сервер находится в сеансе? – djmj 5 November 2012 в 03:29

Еще один пример:

get метод класса Hibernate Session возвращает значение null, если объект не найден в кеше, а также в базе данных. а метод load () вызывает ObjectNotFoundException, если объект не найден в кеше, а также в базе данных, но никогда не возвращает null.

2
ответ дан Ask_Me_A_Question 27 August 2018 в 23:14
поделиться

Отличное объяснение содержится в http://www.mkyong.com/hibernate/different-between-session-get-and-session-load session.load (): оно всегда будет верните «прокси» (термин Hibernate) без попадания в базу данных. В Hibernate прокси - объект с данным значением идентификатора, его свойства еще не инициализированы, он просто выглядит как временный поддельный объект. Он всегда будет возвращать прокси-объект с заданным значением идентичности, даже значение идентификатора не существует в базе данных. Однако при попытке инициализировать прокси-сервер, извлекая его свойства из базы данных, он попадет в базу данных с помощью оператора select. Если ни одна строка не найдена, объект ObjectNotFoundException будет бросать. session.get (): он всегда попадает в базу данных (если не найден в кеше) и возвращает реальный объект, объект, представляющий строку базы данных, а не прокси. Если строка не найдена, она возвращает null.

0
ответ дан black jack 27 August 2018 в 23:14
поделиться

Ну, по крайней мере, в nhibernate session.Get (id) будет загружать объект из базы данных, а session.Load (id) создает для него прокси-объект, не покидая ваш сервер. Работает точно так же, как и все остальные лениво загруженные объекты в ваших POCOs (или POJO :). Затем вы можете использовать этот прокси-сервер в качестве ссылки на сам объект, чтобы создавать отношения и т. Д.

Подумайте об этом как о наличии объекта, в котором хранится только Id, и который загрузит остальное, если вам когда-нибудь понадобится. Если вы просто передаете его для создания отношений (например, FK), идентификатор - это все, что вам когда-либо понадобится.

14
ответ дан Jorge Alves 27 August 2018 в 23:14
поделиться
  • 1
    поэтому вы хотите сказать, что load (id) сначала попадет в базу данных, чтобы проверить, является ли он действительным id или нет, и чем будет возвращать прокси-объект, а когда свойства этого объекта будут доступны, он снова попадает в базу данных? разве это маловероятный сценарий? два запроса на загрузку одного объекта? – faisalbhagat 18 September 2014 в 15:44
  • 2
    Нет, load (id) не будет проверять идентификатор вообще, так что нет никаких обходов в DB. Используйте его только тогда, когда вы уверены, что уверены, что он действителен. – Jorge Alves 22 September 2014 в 21:23

Также мы должны быть осторожны при использовании нагрузки, поскольку она будет генерировать исключение, если объект отсутствует. Мы должны использовать его только тогда, когда мы уверены, что объект существует.

0
ответ дан Sanjay 27 August 2018 в 23:14
поделиться

Одним из косвенных последствий использования «нагрузки» вместо «get» является то, что оптимистическая блокировка с использованием атрибута версии может работать не так, как вы ожидали. Если загрузка просто создает прокси и не читает из базы данных, свойство version не загружается. Версия будет загружаться только тогда, когда / если вы позже обратитесь к свойству объекта, вызывая выбор. Тем временем другой сеанс может обновить объект, и ваш сеанс не будет иметь оригинальную версию, чтобы выполнить оптимистичную проверку блокировки - поэтому обновление вашего сеанса будет перезаписывать обновление другого сеанса без предупреждения.

Вот попытка набросать этот сценарий двумя сеансами работы с объектом с тем же идентификатором. Начальная версия для объекта в БД - 10.

Session 1                  Session 2
---------                  ---------
Load object
Wait a while..   
                           Load object
                           Modify object property
                           [triggers db 'select' -
                            version read as 10]
                           Commit
                           [triggers db update,
                            version modified to 11]
Modify object property
  [triggers db 'select' -
  version read as 11]
Commit
  [triggers db update,
  version modified to 12]

Мы действительно хотим, чтобы фиксация сеанса 1 завершилась неудачей с исключением оптимистичной блокировки, но она преуспеет здесь.

Используя команду "get" вместо «load» работает вокруг проблемы, потому что get немедленно выдает выбор, а номера версий будут загружаться в правильные времена для проверки оптимистичной блокировки.

1
ответ дан SteveT 27 August 2018 в 23:14
поделиться

session.load () всегда возвращает «прокси» (термин Hibernate) без попадания в базу данных. В Hibernate прокси - объект с данным значением идентификатора, его свойства еще не инициализированы, он просто выглядит как временный поддельный объект. Если ни одна строка не найдена, она будет вызывать ObjectNotFoundException.

session.get () всегда попадает в базу данных и возвращает реальный объект, представляющий строку базы данных, а не прокси. Если строка не найдена, она возвращает null.

Производительность с этими методами также делает diff. между двумя ...

9
ответ дан Vishal Sharma 27 August 2018 в 23:14
поделиться

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

Метод get () возвращает значение null, если объект не может быть найденным. Метод load () может возвращать прокси вместо реального постоянного экземпляра get () никогда не возвращает прокси.

0
ответ дан Yasser 27 August 2018 в 23:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: