Отличается между session.get () и session.load ()

Отличается между session.get () и session.load ()

Часто вы замечаете, что разработчики Hibernate смешивают использованиеsession.get() иsession load(). Вам интересно, в чем разница и когда следует использовать любое из них?

Отличается между session.get () и session.load ()

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

1. session.load()

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

  • Если строка не найдена, будет выданObjectNotFoundException.

2. session.get()

  • Он всегдаhit the database и возвращает реальный объект, объект, представляющий строку базы данных, а не прокси.

  • Если строка не найдена, возвращаетсяnull.

Речь идет о производительности

Hibernate создает что-либо по каким-то причинам. Когда вы выполняете ассоциацию, обычно получается получить объект (постоянный экземпляр) из базы данных и назначить его в качестве ссылки на другой объект, просто чтобы сохранить связь. Давайте рассмотрим несколько примеров, чтобы понять, в какой ситуации вам следует использоватьsession.load().

1. session.get()

Например, в приложении Stock, Stock и StockTransactions должны иметь отношение «один ко многим», когда вы хотите сохранить транзакцию с акциями, обычно объявляется что-то вроде ниже

           Stock stock = (Stock)session.get(Stock.class, new Integer(2));
           StockTransaction stockTransactions = new StockTransaction();
           //set stockTransactions detail
           stockTransactions.setStock(stock);
           session.save(stockTransactions);

Выход

Hibernate:
    select ... from example.stock stock0_
    where stock0_.STOCK_ID=?
Hibernate:
    insert into example.stock_transaction (...)
    values (?, ?, ?, ?, ?, ?)

В session.get () Hibernate попадет в базу данных, чтобы получить объект Stock и поместит его в качестве ссылки на StockTransaction. Тем не менее, этот процесс сохранения является чрезвычайно высоким требованием, может быть тысячи или миллионы транзакций в час. Как вы думаете, это необходимо для попадания в базу данных, чтобы получить все объекты Stock, кроме записи транзакции акций? В конце концов вам просто нужен идентификатор акции в качестве ссылки на StockTransaction.

2. session.load()

В приведенном выше сценарииsession.load() будет вашим хорошим решением, давайте посмотрим на пример,

           Stock stock = (Stock)session.load(Stock.class, new Integer(2));
           StockTransaction stockTransactions = new StockTransaction();
           //set stockTransactions detail
           stockTransactions.setStock(stock);
           session.save(stockTransactions);

Выход

Hibernate:
    insert into example.stock_transaction (...)
    values (?, ?, ?, ?, ?, ?)

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

исключение

В исключительном случае см. Примеры

session.load()

Stock stock = (Stock)session.load(Stock.class, new Integer(100)); //proxy

 //initialize proxy, no row for id 100, throw ObjectNotFoundException
System.out.println(stock.getStockCode());

Он всегда будет возвращать прокси-объект с заданным значением идентификатора, даже если значение идентификатора не существует в базе данных. Однако, когда вы пытаетесь инициализировать прокси-сервер, получая его свойства из базы данных, он попадает в базу данных с помощью оператора select. Если строка не найдена, будет выданObjectNotFoundException.

org.hibernate.ObjectNotFoundException: No row with the given identifier exists:
[com.example.common.Stock#100]

session.get()

//return null if not found
Stock stock = (Stock)session.get(Stock.class, new Integer(100));
System.out.println(stock.getStockCode()); //java.lang.NullPointerException

Он всегда будет возвращать ноль, если значение идентичности не найдено в базе данных.

Заключение

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