2014-05-11 273 views
-1
SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); 
     Session session = sessionFactory.openSession(); // create session object 
     session.beginTransaction(); // start transaction object 
     session.save(user); // save the user to database 
     session.getTransaction().commit(); // commit the transaction 
     session.close(); // closing session 

     session = sessionFactory.openSession(); 
     user = null; 
     user = (UserDetails) session.get(UserDetails.class, 1); 
     System.out.println(user.getLisOfAddresses().size()); 
    } 
} 

OUTPUT:看保健充分的輸出有兩個選擇查詢一個是用戶,另一個是地址表時,我們稱之爲getListOfAddresses();延遲加載

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version). 
log4j:WARN Please initialize the log4j system properly. 
Hibernate: insert into USER_DETAIL (USER_NAME) values (?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as USER2_0_0_ from USER_DETAIL userdetail0_ where userdetail0_.USER_ID=? 
Hibernate: select lisofaddre0_.USER_ID as USER1_0_, lisofaddre0_.CITY_NAME as CITY2_0_, lisofaddre0_.PIN_CODE as PIN3_0_, lisofaddre0_.STATE_NAME as STATE4_0_, lisofaddre0_.STREET_NAME as STREET5_0_ from USER_ADDRESS lisofaddre0_ where lisofaddre0_.USER_ID=? 
2 

現在,如果你改變一些代碼行該類文件以驗證代理對象。 在調用getListOfAddresses()方法關閉會話之前,會發生這種情況。

  session = sessionFactory.openSession(); // again create another session object 
     user = null; 
     user = (UserDetails) session.get(UserDetails.class, 1); 
      session.close(); // close the session before calling collection getter 
     System.out.println(user.getLisOfAddresses().size()); 

現在輸出:

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version). 
log4j:WARN Please initialize the log4j system properly. 
Hibernate: insert into USER_DETAIL (USER_NAME) values (?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as USER2_0_0_ from USER_DETAIL userdetail0_ where userdetail0_.USER_ID=? 
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.sdnext.hibernate.tutorial.dto.UserDetails.lisOfAddresses, no session or session was closed 
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException 
(AbstractPersistentCollection.java:380) 
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected 
(AbstractPersistentCollection.java:372) 
    at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:119) 
    at org.hibernate.collection.PersistentBag.size(PersistentBag.java:248) 
    at com.sdnext.hibernate.tutorial.HibernateTestDemo.main(HibernateTestDemo.java:48) 

正如上面的代碼失敗的運行,因爲當我們使用抓取物體的延遲型戰略Hibernate的Session返回代理對象,它在會話中如果我們正在關閉會話,延遲加載不會發生。

對於預先抓取:

SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); 
     Session session = sessionFactory.openSession(); 
     session.beginTransaction(); 
     session.save(user); 
     session.getTransaction().commit(); 
     session.close(); 

     session = sessionFactory.openSession(); 
     user = null; 
     user = (UserDetails) session.get(UserDetails.class, 1); 
     session.close(); //closing the session before calling collection getter 
     System.out.println(user.getLisOfAddresses().size()); 
     } 
} 

OUTPUT:

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version). 
log4j:WARN Please initialize the log4j system properly. 
Hibernate: insert into USER_DETAIL (USER_NAME) values (?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: insert into USER_ADDRESS (USER_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?) 
Hibernate: select userdetail0_.USER_ID as USER1_0_0_, userdetail0_.USER_NAME as USER2_0_0_, lisofaddre1_.USER_ID as USER1_2_, lisofaddre1_.CITY_NAME as CITY2_2_, lisofaddre1_.PIN_CODE as PIN3_2_, lisofaddre1_.STATE_NAME as STATE4_2_, lisofaddre1_.STREET_NAME as STREET5_2_ from USER_DETAIL userdetail0_ left outer join USER_ADDRESS lisofaddre1_ on userdetail0_.USER_ID=lisofaddre1_.USER_ID where userdetail0_.USER_ID=? 

2 ************************* ************************************************** *** 查看此代碼是否成功運行,因爲我們使用EAGER獲取策略,因此在此策略會話中返回原始對象,並且所有字段在加載到內存時都被初始化。 在上面的輸出字符串中,完全看起來只有一個帶連接子句的select語句。

我只是想知道,即使在顯式關閉SESSION,

System.out.println(user.getLisOfAddresses().size()); 

執行罰款。 因此,從上述收藏處休息。來自第一級CACHE。 即使在EAGER放棄會議後(即我知道依賴的對象也加載),對象是否仍然存在?什麼是懶惰負荷的情況?因爲收藏品都是沒有加載,難道是這個原因,

System.out.println(user.getLisOfAddresses().size()); 

顯示錯誤在遲緩裝載後會話關閉和getter被調用後關閉會話? COULS有人反映了這個? 我知道什麼是懶惰和EAGER抓取?

回答

1

對一個問題的問題太多。那麼,Hibernate正在做你剛纔要求它做的事情。 您需要知道的getload之間的區別。當你得到的時候,Hibernate從DB獲取並且反對。當你做load Hibernate製作和代理對象,並不會加載對象,直到你真的需要它(直到你打電話給它或類似的東西)。

I JUST WISH TO KNOW THAT EVEN AFTER CLOSING THE SESSION EXPLICITLY, 

System.out.println(user.getLisOfAddresses().size()); 

EXECUTES FINE. 

是它,閉幕會議不會使你的初始化(從數據庫對象讀取)爲null,而是讓這些對象detached。查看從hibernate文檔中分離出來的意思。但是物體本身會一直存在,直到GC破壞它爲止。

`SINCE THE COLLECTION IS NOT LOADED, IS IT THIS VERY REASON THAT 

System.out.println(user.getLisOfAddresses().size()); 

SHOWS ERROR IN LAZY LOADING AFTER SESSION IS CLOSED AND GETTER IS CALLED AFTER CLOSING THE SESSION 

這正是分離對象+延遲加載的原因。您的LisOfAddresses未加載,並且user對象已分離(表示未附加任何休眠會話)。所以它有代理,試圖打數據庫假設user對象連接到休眠會話這是錯誤的在你的情況下,失敗,這是正確的。