Впадать в спящий режим:Разница между session.get и session.load

StackOverflow https://stackoverflow.com/questions/608947

Вопрос

Из API я мог видеть, что это как-то связано с прокси.Но я не смог найти много информации о прокси и не понимаю разницы между вызовом session.get и session.load.Не мог бы кто-нибудь, пожалуйста, объяснить или направить меня на справочную страницу?

Спасибо!!

Это было полезно?

Решение

Из самого Перевести форум в спящий режим:

Это из книги "Гибернация в действии".Хороший человек, прочитавший это..


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

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

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

Другие советы

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

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

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

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

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

Еще Одно дополнительное очко::

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

Одним из косвенных последствий использования "load" вместо "get" является то, что оптимистичная блокировка с использованием атрибута version может работать не так, как вы ожидали.Если загрузка просто создает прокси-сервер и не выполняет чтение из базы данных, свойство 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 немедленно выдаст select, и номера версий будут загружены в нужное время для проверки оптимистичной блокировки.

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top