简体   繁体   English

理解hibernate中的session.get vs session.load方法

[英]understanding session.get vs session.load method in hibernate

I am not able to understand the difference between load and get . 我无法理解load和get之间的区别。 the following piece of code doesn't work when i give session.load. 当我给session.load时,下面的代码不起作用。 It gives null pointer exception. 它给出了空指针异常。 But same does work when i am using session.get() . 但是当我使用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.? 我还想了解如何将Session对象传递给doInHibernate。
when does session starts and when it ends? 会话何时开始以及何时结束?

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$1.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)
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. 主要区别在于:如果load()无法在缓存或数据库中找到对象,则抛出异常。 The load() method never returns null. load()方法永远不会返回null。 The get() method returns null if the object can't be found. 如果找不到对象,则get()方法返回null。 Other difference is that the load() method may return a proxy instead of a real instance but get() never does return proxy. 另一个区别是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 如果找不到对象,则load方法将抛出异常,但会得到NOT.Simple

Edit: To elaborate the things, 编辑:详细说明事情,

  1. When get() method is called, it will directly hit the database, fetch the result and return. 当调用get()方法时,它将直接命中数据库,获取结果并返回。 If no matching fields are found, it will gladly return null. 如果找不到匹配的字段,它将很乐意返回null。

  2. But when load() executes, firstly it will search the cache for required object. 但是当load()执行时,它首先会在缓存中搜索所需的对象。 If found, all is well. 如果找到,一切都很好。 But if object is not found in cache, load() method will return a proxy. 但是如果在缓存中找不到对象,则load()方法将返回一个代理。 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. 现在,当您实际访问该对象时,将跟踪代理并进行数据库命中。

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, ie line 2, the proxy will be traced and the database will be hit. 如果具有主键1的User对象在会话中不可用,则load()方法将在第1行为数据库设置代理。现在当调用'user'对象的实际值时,即第2行,代理将是跟踪,数据库将被击中。

Hope this will help. 希望这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM