Hibernate 異常org.hibernate.LazyInitializationException

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 默認加載一層數據。 不會無限深入加載。 這一點考慮得還是很周到的。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章