2011-08-03 57 views
6

我無法理解load和get之間的區別。當我給session.load時,下面的一段代碼不起作用。它給出空指針異常。但是,當我使用session.get()時,它也可以工作。瞭解session.get vs session.load方法在休眠中

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); 
    } 

我也想明白了Session對象是如何傳遞到doInHibernate?
會話何時開始以及何時結束?

堆棧跟蹤是如下

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) 
+0

你是什麼意思的「不工作」?什麼是導致NullPointerException的行? –

+1

Google for「at org.hibernate.tuple.AbstractEntityTuplizer.createProxy(AbstractEntityTuplizer.java:372)」。你運行的是舊版本的Hibernate,我發現了這個異常的幾個可能的原因(壞映射,壞罐子等)。它與load和get沒有多大關係。 –

+0

@JB Nizet:非常感謝!我會檢查我的構建配置,並將更新舊的罐子,我有很多次面臨這個問題,並正在學習項目的初始化......但你能否幫助我解決其他疑問.i.e。 ** Session對象如何傳遞給doInHibernate。 會話何時開始以及何時結束?** –

回答

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

的主要區別在於:如果負載()不能找到在緩存或數據庫中的對象,則拋出異常。 load()方法永遠不會返回null。如果找不到對象,則get()方法返回 。 其他區別在於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() . 

如果未找到對象,load方法會拋出異常,但得到won't.Simple

編輯: 要闡述的東西,

  1. 當get()方法方法被調用,它會直接命中數據庫,獲取結果並返回。如果找不到匹配的字段,它會很樂意返回null。

  2. 但是,當load()執行時,首先它會搜索緩存中的所需對象。如果找到了,一切都很好。但是如果在緩存中找不到對象,load()方法將返回一個代理。您可以將此代理視爲數據庫查詢執行的快捷方式。請記住,沒有數據庫命中。現在,當您實際訪問該對象時,將會跟蹤代理並創建數據庫命中。

讓我們考慮一個簡單的例子。

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

如果具有主鍵1用戶對象不在會話中可用時,負載()方法將設置一個代理在1號線數據庫現在,當「用戶」對象的實際值被調用時,即第2行,代理將被追蹤並且數據庫將被命中。

希望這會有所幫助。

+1

否:加載不查找數據庫中的對象。它返回它在它的會話緩存中擁有的對象,或者創建一個代理,假設該對象存在於數據庫中。 –

+0

@Pravin:我已經從手冊中讀到了這個內容我想讓某人向我解釋你剛剛告訴的內容......當說到load方法返回代理而不是真實實例時,我知道它從某個緩存返回數據並且因此加載方法不需要多個數據點擊到數據庫。我也明白空值指針異常發生在空值被引用時,我的問題是爲什麼它是空的,我如何使它與加載工作,所以你的答案是根本沒有任何幫助 –

+0

@Anupam,我編輯了這篇文章,使事情更清晰。我希望這會恢復我失去的代表。 –