Hibernate的load()方法对不存在的ID做了什么?

时间:2011-09-14 20:34:32

标签: java hibernate

我对Session.load上的JavaDocs感到有点困惑:

  

返回具有给定标识符的给定实体类的持久化实例,假设   该实例存在。此方法可能会返回按需初始化的代理实例,   当访问非标识符方法时。

     

您不应该使用此方法来确定是否存在实例(请改用get())。用这个   只检索你认为存在的实例,其中不存在将是一个实际的错误。

我理解我应该使用get,但是我不明白的是当使用非标识符方法时,根据需要初始化它的含义是什么意思。

对我来说,如果我有一个类并使用load(MyClass.class, NonExistingID),然后在返回的实例上打印getId()的输出,它似乎会自动生成一个NonExistingID的新实例每一次。这是为什么?

我只是想了解,getId()是一种非识别方法吗?

2 个答案:

答案 0 :(得分:7)

长话短说:

session.load 将创建代理对象,当您调用任何非主要密钥类项的getter时,该代理对象将被初始化。

如果对象不存在,

session.get 将返回null,如果该对象存在则返回完整对象。

答案 1 :(得分:5)

'非标识符方法'表示返回对象之外的标识符(如在主键id中)的方法。 load为您提供代理服务器,代理服务器只在您询问数据库以外的其他内容时才会查询数据库。所以getId是一个标识符方法,Hibernate不会在数据库中查询它的值(它没有,因为你将它传递给load方法调用)。

the hibernate forums上找到此代码段:

  

一个重要的场景,你需要对比负载和   获取Hibernate Session的方法与何时发生的事情有关   您提供的数据库中实际不存在的主键。   好吧,使用get方法,只需返回一个null对象,   这没什么大不了的。

     

使用加载方法,提供时也没有初始问题   方法的无效主键。从你能说的,   Hibernate似乎会把你带回一个有效的非null实例   你感兴趣的课程。但问题出现的时候   你实际上试图访问该实例的属性 - 就在那里   你遇到了麻烦。

     

还记得我说过load方法直到a才打到数据库   请求bean的属性?好吧,如果你提供了一个小学   数据库中不存在与load方法相关的键   确实是第一次去数据库,它将无法找到   不存在的相关记录,你的代码会咳得很大   时间。实际上,查找基于不存在的主要字段的字段   使用Hibernate Session的load方法触发以下操作   错误:

     

org.hibernate.ObjectNotFoundException:没有给定的行   标识符存在:[用户#123]

所以听起来你已经使用了load来获取一个不存在的对象的代理,但由于你没有在其上调用任何'nonidentifier方法',你没有强制代理命中数据库而没有得到了一个错误。