我有以下代碼: 這User是一個休眠域。
for(User user : users) {
try {
function()
//log the user content
} catch(Exception ex) {
log.warn("Exception " ex.toString() ". Continue...")
}
}
一些欄位User正在延遲加載。在function()拋出例外的情況下,延遲加載會拋出no Session例外,因此用戶內容日志記錄被破壞。盡管
for(int i=0; i<users.size(); i) {
var user = users.get(i)
try {
function()
//log the user content
} catch(Exception ex) {
log.warn("Exception " ex.toString() ". Continue...")
}
}
作業正常。我真的需要了解這個問題的根本原因,所以任何提示都值得贊賞。
uj5u.com熱心網友回復:
很難說到底發生了什么,但可能在某個時候拋出了一個例外,這會清除 Hibernate 會話,并且下次訪問代理時會拋出LazyInitializationException.
參見例如https://docs.grails.org/5.1.7/guide/single.html#declarativeTransactions
[Transactional] 方法包裝在事務中,如果方法拋出例外(檢查例外或運行時例外),則會發生自動回滾
https://docs.grails.org/5.1.7/guide/single.html#transactionsRollbackAndTheSession提到
當事務回滾時,GORM 使用的 Hibernate 會話被清除。這意味著會話中的任何物件都將被分離,并且訪問未初始化的延遲加載集合將導致 LazyInitializationException。
我認為這也是您的情況。我不確定為什么它不會出現在您發布的第二個代碼中,也許users.get(i)代碼實際上再次從您的資料庫中獲取物件。
其他解決方法包括:
- 重新撰寫您的代碼,以便不會引發例外并保留會話
- 為每個物件使用單獨的會話 (
User.withNewSession { ... }) -> 不利于性能 - 發生例外后重新獲取物件(如果您必須經常這樣做也不是最佳選擇)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/461534.html
