(1), (3):
Да.Вы правы. Обе load()
и get()
сначала проверит, сохранился ли экземпляр с тем же PK в сеансе.
Если да, просто возвращает этот экземпляр из сеанса.(Это может быть прокси или фактический экземпляр класса сущности)
Если нет, load()
создаст и вернет прокси, в то время как get()
ударит по БД и вернет экземпляр фактического класса сущности.
Возвращенный объект из обоих методов будет связан и сохранен в сеансе позже.
Таким образом, 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.
После того, как прокси-сервер получит доступ к БД, экземпляр с тем же 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()
полезно при установке ограничения внешнего ключа.См это