簡體   English   中英

如何解決org.hibernate.LazyInitializationException?

[英]how can to resolve org.hibernate.LazyInitializationException?

org.hibernate.LazyInitializationException :無法延遲初始化角色集合:com.t4bt.gov.persistence.entities.Experts.institutaionList,沒有會話或會話被關閉

您在問題中提供的細節很少(代碼?),因此它必須是關於延遲加載的通用答案。 將來,如果您需要答案,請提供有關實際問題的具體信息,以及有關您試圖解決的問題的描述。

當您在會話關閉后(通常是在事務結束之后)嘗試訪問延遲加載的屬性時,就會發生LazyInitialization。 惰性初始化的工作方式是,當您獲取對象時,它不會獲取延遲初始化的屬性,但是當您實際嘗試訪問它時,Hibernate會對數據庫進行另一個查詢以獲取它。

以下將產生這樣的錯誤:

public class Something {
    [...]
    @OneToMany(fetch = FetchType.LAZY)
    private List<SomethingElse> somethingElse;

    public List<SomethingElse> getSomethingElse() {
        return somethingElse;
    }
}

public class SomethingDao {
    @Inject
    private EntityManager em;

    @Transactional
    public Something getById(final Integer id) {
        return em.find(Something.class, id);
    }
}

public class SomethingService {
    @Inject
    private SomethingDao dao;

    public List<SomethingElse> getSomethingElseForSomething(final Integer somethingId) { 
        final Something something = dao.getById(somethingId);
        return something.getSomethingElse() //Throws LazyInitializationException
    }
}

在這里,事務(以及會話)僅存在於dao類中。 離開dao方法后,會話就消失了。 因此,當您嘗試訪問服務中的延遲加載屬性時,當Hibernate嘗試聯系會話以檢索它時,它將失敗。

為了避免這種情況,有幾種可能性。

  1. 將Something類的批注更改為@OneToMany(fetch = FetchType.EAGER)該屬性不再延遲加載,因此不再有問題。
  2. @Transactional添加到Service-method。 然后,對getSomethingElse()的調用將與獲取Something對象的事務處於同一事務中,並且這樣做時會話仍將保持活動狀態。
  3. 在Dao方法中添加對getSomethingElse()的調用。 然后,它將在離開Dao類(和事務)之前初始化屬性(從數據庫中獲取屬性),並且該屬性將在事務外部可用,而無需與會話進行通信即可檢索它。

暫無
暫無

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

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