簡體   English   中英

Hibernate中的LazyInitializationException:無法初始化代理 - 沒有Session

[英]LazyInitializationException in Hibernate : could not initialize proxy - no Session

我把我的服務稱為dao

@Override
@Transactional
public Product getProductById(int id) {
    return productDao.getProductById(id);
}

在dao我得到的產品

@Override
public Product getProductById(int id) {
    Product p = sessionFactory.getCurrentSession().load(Product.class, id);
    System.out.print(p);
    return p;
}

這運行正常,但如果我將我的dao類更改為

@Override
public Product getProductById(int id) {
    return sessionFactory.getCurrentSession().load(Product.class, id);
}

我得到org.hibernate.LazyInitializationException:無法初始化代理 - 沒有Session。 我正在打印產品的視圖層中發生異常。 我不明白為什么在dao方法中返回同一行導致視圖層中的異常,但如果我將它保存在引用中然后返回它,則工作正常。

這里有一個很好的參考 ,讓您熟悉.get()和.load()方法的工作原理。

@Override
public Product getProductById(int id) {
    Product p = sessionFactory.getCurrentSession().load(Product.class, id);
    return p;
}

session.load()默認返回代理對象而不命中數據庫。 如果表上沒有任何記錄,它基本上會返回NoObjectFoundError ,否則它將返回一個引用,而不會填充實際對象甚至命中數據庫。 您的上述方法返回一個代理,因為它也必須初始化您的對象,會話保持打開狀態並填充對象。

@Override
public Product getProductById(int id) {
    return sessionFactory.getCurrentSession().load(Product.class, id);
}

但在第二種方法中,基本上返回代理而不進行任何初始化。 會議在此后關閉,無需事先使用。 因此,你得到錯誤。

希望有所幫助

此錯誤意味着您正在嘗試訪問延遲加載的屬性或集合,但hibernate會話已關閉或不可用。 Hibernate中的延遲加載意味着在代碼中訪問屬性/集合之前,不會填充對象(通過數據庫查詢)。 Hibernate通過創建一個動態代理對象來實現這一點,該對象僅在您第一次使用該對象時才會訪問數據庫。 為了實現這一點,您的對象必須在整個生命周期中附加到一個打開的Hibernate會話。

如果刪除SOP語句,則根本不訪問對象,因此不加載。 當您嘗試在其他部分代碼中訪問它時,它將拋出LazyInitializationException。

當您處理Hibernate和視圖層時,這是一個典型的問題。 發生錯誤是因為在呈現視圖之前Hibernate會話已關閉。 解決此問題的兩種最簡單方法是使用Open Session In View模式或在視圖呈現之前獲取視圖中所需的所有數據。

由於您使用的是Spring,因此第一個解決方案是最簡單的 - 只需應用OpenSessionInViewFilter (如果使用JPA,則應用OpenEntityManagerInViewFilter ):

http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/orm/hibernate4/support/OpenSessionInViewFilter.html http://docs.spring.io/spring/docs/current /javadoc-api/org/springframework/orm/jpa/support/OpenEntityManagerInViewFilter.html

您還應該了解使用OSIV模式的優缺點。

在您的Product實體中,嘗試在OneToMany關系注釋中添加fetch = FetchType.EAGER,例如

@OneToMany(mappedBy =“employee”,fetch = FetchType.EAGER)

這將加載整個Product對象圖,避免后續調用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM