failed to lazily initialize a collection of role: no session or session was closed (Hibernate) 解決方法(延遲載入問題)
在學著編寫OA 許可權管理時,在jsp 頁面中通過已取得的 父模組來獲取該模組的所有子模組
JSP 程式碼片段:
<c:forEach items="${modules}" var="module">
<c:forEach items="${module.children}" var="child">
<td> ${child.name }</td>
java 程式碼:
@OneToMany(mappedBy="parent")
public Set<Module> getChildren() {
return children;
}
在這段程式碼中沒有對延遲載入進行設定,在JSP頁面顯示時報了failed to lazily initialize a collection of role: no session or session was closed (Hibernate) 的錯誤。
通過BAIdu 一下,發現我犯了延遲hibernate 延遲載入方面的錯誤。
修改程式碼後
@OneToMany(mappedBy="parent", fetch = FetchType.EAGER)
public Set<Module> getChildren() {
return children;
}
Hibernate: select module0_.id as id3_, module0_.name as name3_, module0_.orderNum as orderNum3_, module0_.parentId as parentId3_, module0_.sn as sn3_, module0_.url as url3_ from Module module0_ where module0_.parentId is null limit ?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
Hibernate: select children0_.parentId as parentId1_, children0_.id as id1_, children0_.id as id3_0_, children0_.name as name3_0_, children0_.orderNum as orderNum3_0_, children0_.parentId as parentId3_0_, children0_.sn as sn3_0_, children0_.url as url3_0_ from Module children0_ where children0_.parentId=?
雖然這種方式在查詢模組時會進行大量的SQL操作,但在本次實踐中作為一個練習是可行的。
頁面顯示正常,能夠獲取到該模組的子模組。通過檢視hibernate打印出的sql 語句,可以看出hibernate在取出父模組的同時也將其關聯的子模組全部取出。
為了驗證 @OneToMany(mappedBy="parent", fetch = FetchType.LAZY)
public Set<Module> getChildren() {
return children;
}
是否能夠取得理想效果,我修改了程式碼後,JSP 頁面仍然報同樣的錯誤,提示不能載入子模組。
雖然設定了延遲載入,如果是在java 程式碼中應該可以實現延遲載入功能。但是在這裡,使用jsp 頁面呼叫的方式,Action 將參賽傳遞到JSP頁面中後,session 已經關閉,而JSP頁面中的modules 是通過session 從Action中獲取的。在session 已經關閉時,希望通過modules 延遲載入(也就是重新發SQL 語句到資料庫中取到其子模組的實體類) 是不可能實現的。
檢視hibernate 列印的sql 語句證實了其只能查詢出該實體類本身的屬性,而不能查詢出與其關聯的屬性
Hibernate: select module0_.id as id3_, module0_.name as name3_, module0_.orderNum as orderNum3_, module0_.parentId as parentId3_, module0_.sn as sn3_, module0_.url as url3_ from Module module0_ where module0_.parentId is null limit ?
為了弄清楚延遲載入,又baidu了一把,總結下延遲載入:
A,實體物件的延遲載入: 通常在用 load() 方法時使用。此時返回的是實體類的代理類。而在對該實體類進行操作時,hibernate才會去資料庫獲取真正的實體類物件
B,集合型別的延遲載入: 就是本文提到的父模組與子模組之間的關係,在這裡提醒一下,在實體類中定義子物件集時,必須使用set 集合。
C, 屬性延遲載入: 通常對某個實體類進行細分,設定該實體類的某些屬性為延遲載入,但需要對這些屬性進行操作時,才去讀取這些屬性在資料庫中的column 值