java 了解休眠中的 session.get 与 session.load 方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6924799/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 17:54:51  来源:igfitidea点击:

understanding session.get vs session.load method in hibernate

javahibernatespringsessiontransactions

提问by Anupam Gupta

I am not able to understand the difference between load and get . the following piece of code doesn't work when i give session.load. It gives null pointer exception. But same does work when i am using session.get() .

我无法理解 load 和 get 之间的区别。当我给 session.load 时,以下代码不起作用。它给出了空指针异常。但是当我使用 session.get() 时同样有效。

public Employee getEmployee(final String id){        
        HibernateCallback callback = new HibernateCallback() {
            public Object doInHibernate(Session session) 
                throws HibernateException,SQLException {
                //return (Employee)session.load(Employee.class, id);   doesn't work
                  return (Employee)session.get(Employee.class, id);    //it works
            }
        };        
        return (Employee)hibernateTemplate.execute(callback);
    }

I also want to understand how Session object is passed to doInHibernate.?
when does session starts and when it ends?

我也想了解 Session 对象是如何传递给 doInHibernate 的。?
会话什么时候开始,什么时候结束?

Stack trace is as follows

堆栈跟踪如下

Exception in thread "main" java.lang.NullPointerException
    at org.hibernate.tuple.AbstractEntityTuplizer.createProxy(AbstractEntityTuplizer.java:372)
    at org.hibernate.persister.entity.AbstractEntityPersister.createProxy(AbstractEntityPersister.java:3121)
    at org.hibernate.event.def.DefaultLoadEventListener.createProxyIfNecessary(DefaultLoadEventListener.java:232)
    at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:173)
    at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:87)
    at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:862)
    at org.hibernate.impl.SessionImpl.load(SessionImpl.java:781)
    at org.hibernate.impl.SessionImpl.load(SessionImpl.java:774)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.orm.hibernate3.HibernateTemplate$CloseSuppressingInvocationHandler.invoke(HibernateTemplate.java:1282)
    at $Proxy0.load(Unknown Source)
    at hibernate.EmployeeDao.doInHibernate(EmployeeDao.java:25)
    at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
    at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:339)
    at hibernate.EmployeeDao.getEmployee(EmployeeDao.java:29)
    at hibernate.SpringHibernateTest.main(SpringHibernateTest.java:26)

回答by santosh-patil

I am not able to understand the difference between load and get 

The main difference is: if load() can't find the object in the cache or database, an exception is thrown. The load() method never returns null. The get() method returns null if the object can't be found. Other difference is that the load() method may return a proxy instead of a real instance but get() never does return proxy.

主要区别在于:如果 load() 在缓存或数据库中找不到对象,则抛出异常。load() 方法从不返回 null。如果找不到对象,get() 方法将返回 null。另一个区别是 load() 方法可能返回一个代理而不是一个真实的实例,但 get() 从不返回代理。

the following piece of code doesn't work when i give session.load. It gives null pointer exception. But same does work when i am using session.get() .

If object is not found, load method will throw exception but get won't.Simple

如果没有找到对象,加载方法将抛出异常但获取不会。简单

Edit:To elaborate the things,

编辑:详细说明事情,

  1. When get() method is called, it will directly hit the database, fetch the result and return. If no matching fields are found, it will gladly return null.

  2. But when load() executes, firstly it will search the cache for required object. If found, all is well. But if object is not found in cache, load() method will return a proxy. You can consider this proxy as a shortcut for database query execution. Remember, no database hit is made yet. Now when you actually access the object the proxy will be traced and database hit will be made.

  1. 当get()方法被调用时,它会直接命中数据库,获取结果并返回。如果没有找到匹配的字段,它会很乐意返回 null。

  2. 但是当 load() 执行时,它首先会在缓存中搜索所需的对象。如果找到,一切都很好。但是如果在缓存中没有找到对象,load() 方法将返回一个代理。您可以将此代理视为执行数据库查询的快捷方式。请记住,尚未命中数据库。现在,当您实际访问对象时,将跟踪代理并进行数据库命中。

Lets consider a simple example.

让我们考虑一个简单的例子。

User user=(User)session.load(User.class, new Long(1));//Line 1
System.out.println(user.getPassword());//Line 2

If User object with primary key 1 is not available in session, the load() method will set a proxy for the database at Line 1. Now when actual value of the 'user' object is called, i.e. line 2, the proxy will be traced and the database will be hit.

如果会话中没有主键为 1 的 User 对象,则 load() 方法将在第 1 行为数据库设置一个代理。现在,当调用 'user' 对象的实际值时,即第 2 行,代理将是跟踪和数据库将被命中。

Hope this will help.

希望这会有所帮助。