Ответ 1
(1), (3):
Да. Вы правы. Но сначала load()
и get()
будут проверять наличие экземпляра с тем же PK в сеансе.
Если да, просто возвращает этот экземпляр из сеанса. (Это может быть прокси или фактический экземпляр класса объекта)
Если нет, load()
создаст и вернет прокси-сервер, а get()
ударит DB и вернет экземпляр фактического класса сущности.
Возвращаемый объект из обоих методов будет связан и сохранен в сеансе впоследствии.
Итак, возвращает ли get()
или load()
прокси-сервер или фактический класс сущности зависит от того, используете ли вы get() или load(), чтобы получить экземпляр того же PK в текущем сеансе в первый раз.
Вы можете подтвердить это поведение, выполнив следующий тест:
Session session = HibernateUtil.getSessionFactory().openSession();
Item loadItem= (Item ) session.load(Item.class, 1);
System.out.println(loadItem.getClass().getName());
Item getItem = (Item ) session.get(Item .class, 1);
System.out.println(getItem .getClass().getName());
Если это прокси-сервер, имя печатного класса не будет таким же, как имя класса сущности. Просто измените порядок выполнения на load()
и get()
, чтобы увидеть эффект.
(2):
Если load() возвращает прокси-сервер, он не будет обращаться к БД во время load()
. Прокси будет обращаться к БД только в том случае, если к ним будут применены сопоставленные свойства, кроме ПК, и нет экземпляров с одинаковым значением PK с сеансом.
После того как прокси обратится к БД, экземпляр с тем же PK прокси-сервера будет связан с этим сеансом. Поэтому, когда вы снова получите другие свойства из прокси-сервера или используете get()
, чтобы получить экземпляр для той же PK, DB не будет доступен, поскольку значения могут быть найдены из сеанса.
Например:
/**Session starts***/
Item item = (Item) session.load(Item.class, new Long(1));
item.getId(); //Will not access DB as only the identifier property is access
item.getDescription(); // access the DB and initialize the proxy . After that , the item proxy is said to be initialized
item.getPrice(); //will not access DB as the item with the PK 1 can be get from the session
Item item2 = session.get(Item.class, new Long(1)) //will not access DB as the item with the PK 1 can be get from the session
Если вы load()
экземпляр с недопустимым идентификатором, а затем получите доступ к свойствам или вызовите метод (например, isInitialized()
) в этом прокси, будет выбрано ObjectNotFoundException
. Поэтому, если вы можете поймать ObjectNotFoundException
, это означает, что прокси загружается с недопустимым идентификатором.
Если вы хотите убедиться, что идентификатор действителен во время выполнения, вы должны использовать get()
и проверить, является ли возвращаемый экземпляр нулевым. load()
полезен при настройке ограничения внешнего ключа. См. this