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

Jus*_*yul 6 java hibernate

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

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

您不应该使用此方法来确定是否存在实例(请改用get()).仅用于检索您假定存在的实例,其中不存在将是实际错误.

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

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

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

dan*_*nik 7

只是为了简短说明:

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

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


Nat*_*hes 5

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

在hibernate论坛上找到了这个片段:

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

使用load方法,当您为方法提供无效的主键时,也没有初始问题.从您可以看出,Hibernate似乎将您感兴趣的类的有效非空实例交给您.但是,当您实际尝试访问该实例的属性时,问题就会出现 - 这就是您遇到麻烦的地方.

还记得在请求bean的属性之前我怎么说load方法没有命中数据库?好吧,如果你提供了一个数据库中不存在的主键到load方法,当它第一次进入数据库时​​,它将无法找到不存在的相关记录,你的代码会咳得很快.实际上,使用Hibernate Session的加载方法查找基于不存在的主键的字段会触发以下错误:

org.hibernate.ObjectNotFoundException:不存在具有给定标识符的行:[User#123]

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