1 Hibernate中的lazy(默認true)網上很多人都把它叫懶人機制,主要是告訴Hibernate獲取數據時在什麼時候去讀庫;2lazy只對session.Load和獲取級聯信息(1對1,1對多,多對多)時起作用;
3.Session讀取信息的方式(Load和級聯信息)
3.1延遲加載(lazy=true)
當我用Load或者是該bean中有級聯對象的時候,執行Load的時候並不去讀庫,但Load還是會返回一個對象給你,但該對象中只有主鍵,讀庫是在你使用該對象的其他屬性的時候去讀的; 3.2非延遲加載(lazy=false) 在執行Load的時候就會去把庫中的數據讀取出來;4.出問題的地方
由於我們要保證Session要及時關閉,即Load完之後,我們要執行session.close操作;但是當lazy爲真的時候,在Load的時候並是直接去讀庫,而是等使用裏面屬性的時候纔去讀庫。那麼到你打印信息的時候就會報session已經被關閉的錯誤
LazyInitializationException異常:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.hm.bean.NewsType.newsesByTypeId, no session or session was closedat org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:393)at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:385)at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:378)at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:112)at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:500)at java.lang.String.valueOf(String.java:2854)at java.io.PrintStream.println(PrintStream.java:821)
解決辦法:
一對多的實體中:news_type 新聞類型
private Collection<News> newsesByTypeId; @OneToMany(mappedBy = "newsTypeByTypeId") public Collection<News> getNewsesByTypeId() { return newsesByTypeId; } public void setNewsesByTypeId(Collection<News> newsesByTypeId) { this.newsesByTypeId = newsesByTypeId; }
多對一的實體中:news 新聞
@ManyToOne
@JoinColumn(name = "type_id", referencedColumnName = "type_id", nullable = false)
public NewsType getNewsTypeByTypeId() {
return newsTypeByTypeId;
}
public void setNewsTypeByTypeId(NewsType newsTypeByTypeId) {
this.newsTypeByTypeId = newsTypeByTypeId;
}
如果你想創建一個news對象。 根據news對象調用
News_Type nt= news.getNewsTypeByTypeId(); //返回新聞類型對象
nt.getType_Id();//此時會加載新聞類型對象的屬性。加載完後 session關閉. 但並不會加載news 中的
Collection<News> 。原因見下面
如果你要調用 nt.getNewsesByTypeId()返回新聞類型裏面的所有新聞時 。就會出現LazyInitializationException異常
如果程序繼續返回一個Set<News> 那是不是也要獲取每個新聞的類型呢 ,如此將會出現無限循環。
所以hibernate 默認加載一層數據。 不會無限深入加載。 這一點考慮得還是很周到的。