Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate 3.6-session.get()与session.load()的比较_Hibernate_Jakarta Ee_Orm - Fatal编程技术网

Hibernate 3.6-session.get()与session.load()的比较

Hibernate 3.6-session.get()与session.load()的比较,hibernate,jakarta-ee,orm,Hibernate,Jakarta Ee,Orm,我试图理解Hibernate 3.6的返回对象和行为的区别是什么session.get()和session.load() 从: get(): 返回给定实体类的持久实例 给定标识符,如果没有此类持久实例,则为null。(如果 实例已与会话关联,请返回 实例。此方法从不返回未初始化的实例。) load(): 返回给定实体类的持久实例 给定标识符,假设实例存在。这种方法可能会 当 访问非标识符方法 我有三个问题: javadoc没有说明何时load()可能会返回一个代理-有没有办法提前知道它 当loa

我试图理解Hibernate 3.6的返回对象和行为的区别是什么
session.get()
session.load()

从:

get():

返回给定实体类的持久实例 给定标识符,如果没有此类持久实例,则为null。(如果 实例已与会话关联,请返回 实例。此方法从不返回未初始化的实例。)

load():

返回给定实体类的持久实例 给定标识符,假设实例存在。这种方法可能会 当 访问非标识符方法

我有三个问题:

  • javadoc没有说明何时
    load()
    可能会返回一个代理-有没有办法提前知道它

  • load()
    返回代理时-这意味着
    load()
    没有访问数据库,对吗?那么,如果我为
    load()
    提供了数据库中不存在的标识符,该怎么办?现在,我将在会话中使用一个ID无效的代理(不会出现异常)。现在,我想让另一个持久性实例指向该代理——它能工作吗?对于这个场景,我不需要初始化代理,我只需要它的id(虽然它不在数据库中,所以它无效,但我有id)。所以我想我是在问我的描述是否正确,我是否总是需要在
    load()
    返回的对象
    isInitialized()
    之后签出,以确保它代表一个有效的实体(或至少是一个有效的代理),即具有一个有效的ID

  • 另外,如果
    load()
    返回一个代理,那么会发生什么?因此,代理就是已经与会话关联的实例。然后根据
    get()
    的描述:“如果实例已与会话关联,请返回该实例。”-那么
    get()
    是否返回代理?因为根据
    get()
    的描述:“此方法从不返回未初始化的实例。”

  • 谢谢

    更新

    以下是正确的吗

    (A) 我认为
    load()
    get()
    在进入数据库之前都会先检查会话缓存,所以说它们中的任何一个总是命中数据库,或者总是返回代理是不对的

    (B) 初始化的代理与原始实例不同,您可以在此处阅读:

    (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值相同的实例时,代理才会访问数据库

    代理访问DB后,具有相同代理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()
    一个ID无效的实例,然后在此代理上访问属性或调用方法(如
    isInitialized()
    ),则将抛出
    ObjectNotFoundException
    。因此,如果您可以捕获
    ObjectNotFoundException
    ,则表示代理加载了无效ID


    如果要确保ID在运行时有效,应使用
    get()
    并检查返回的实例是否为null<代码>加载()在设置外键约束时非常有用。见

    1。但是如果我在会话中已经有一个初始化的实例(对于这个ID),它不会返回那个实例,而不是一个代理吗?另外,javadoc说:“这个方法可能会返回一个代理实例”——它没有说“这个方法将永远”。2.这是一种设计缺陷——因为根据你所说的,当我有一个代理时,我想确保它在DB中代表一个实际的ID(我总是想确保它——即使我只使用代理来指向它的其他实例)——那么我在初始化它之前无法知道我使用的ID是有效的,但是在这种情况下,为什么要使用代理呢?3。你是说
    load()
    之后的
    get()
    将返回一个初始化的代理,还是只返回一个初始化的实例?因为如果是后者,那么我们现在在会话中有两个具有相同ID的对象(代理和实例)。顺便说一句,我知道可能有两个代理代表相同的DB ID-正如您在这里看到的:在文本“第二,有可能破坏代理”下--请参阅我原始问题更新中的更多内容。是的。你说得对。你的问题帮助我澄清了一些错误