你的問題是,休眠會議只適用於一個請求。它在請求開始時打開,最後關閉。你猜對了答案:在兩個請求都完成之前,Hibernate會話是關閉的。
究竟發生了什麼?您的實體對象在兩個請求期間都處於活動狀態怎麼樣?它們存儲在HTTP會話中(這是一個不同的東西,稱爲會話)你不會提供關於你正在使用的框架的很多信息,所以我不能給你更多的細節,但可以肯定的是你正在使用的框架以某種方式保持你的實體在HTTP會話中。這就是框架如何讓您輕鬆處理多個請求的相同對象。
當第二個請求的處理開始時,代碼正在試圖訪問由hibernate懶惰地初始化的某個實體(通常是集合的一個元素)。該實體沒有附加到hibernate會話中,因此hibernate在讀取hibernate之前無法初始化hibernate代理。您應該打開一個會話,並在ajax請求處理開始時將您的實體重新附加到它。
編輯:
我會盡量給正在發生什麼幕後的簡要說明。所有java web框架都有一個或多個處理請求的servlet。 servlet通過創建一個將最終產生響應的新線程(HttpResponse)來處理每個請求(HttpRequest)。處理每個請求的方法在該線程內執行。
在請求處理開始時,應用程序應該分配處理所需的資源(Transaction,Hibernate session等)。在處理週期結束時,這些資源被釋放(事務被提交,休眠會話被關閉,JDBC連接被釋放等)。這些資源的生命週期可以由您的框架管理,也可以由您的代碼完成。
爲了支持在無狀態協議HTTP作爲應用程序狀態,我們有HttpSession對象。我們(或框架)在HttpSession上放置了同一客戶端的不同請求週期之間保持相關的信息。
在第一請求休眠的處理讀取(懶惰)從數據庫中的實體。由於延遲初始化,此對象結構的某些部分是hibernate代理對象。這些對象與創建它們的hibernate會話相關聯。
框架從HttpSession對象先前的請求找到實體,當您嘗試處理第二個請求。然後它試圖從一個被懶惰初始化的子實體訪問一個屬性,現在是一個hibernate代理對象。 hibernate代理對象模仿真正的對象,當有人試圖訪問它的一個屬性時,它會要求它的hibernate會話填充來自數據庫的信息。這是你的hibernate代理正在嘗試做的事情。但是它的會話在前一個請求處理結束時關閉了,所以現在它沒有使用hibernate會話來充實(充滿真實信息)。
請注意,您可能已經在第二個請求的開始處打開了一個hibernate會話,但它不知道包含該代理對象的實體,因爲此實體是由不同的休眠狀態讀取的。您應該重新將實體附加到新的休眠會話。
有一個關於如何重新連接分離實體很多討論,但最簡單的方法,現在是session.update(entity)
。
希望它有幫助。
錯誤不談,爲什麼讓兩個不同的調用創建PDF?做一次,堅持它,然後從數據庫中檢索它。 – Makoto
當我寫這個問題時,我想你也是這麼想的。但我希望有更多經驗的人也能證實這一點。只是爲了使它更有用......你能解釋爲什麼在這個特定的場景中「無法初始化代理 - 沒有會話」錯誤?提前致謝。 –
休眠問題。向我們展示Ajax調用背後的代碼,以便我們可以幫助您。 – Jukka