我有休眠pojo class A {B b;一些其他的適當性}對於B類,lazy = true。 當我得到對象A時,B沒有被加載,並且hibernate返回它的代理。當我將這個對象傳遞給另一個模塊時,該模塊遍歷A中的每個對象,當它遇到B.getXXX時,它會拋出LazyInitialization異常。在這種特殊情況下,我不想加載B類,因爲它不是必需的。有沒有什麼辦法,當我調用B方法時,它會返回null或將B的代理轉換爲實際對象B,以便模塊不會引發LazyInitialization錯誤。我不能改變B類的getter,setter作爲普通的類並且被其他類使用。從休眠會話中刪除對象
回答
感謝您的所有建議。 我的應用程序有分層架構。服務 - >管理器 - >道。經理之後Hibernate會話關閉。其他模塊只能通過服務進行交互。打開休眠會話,直到請求完成不是我的選擇。我也不想打數據庫,因爲B的屬性沒有必要填充。我只想用真實對象替換Hibernate代理,以便任何使用服務的人都不會遇到任何問題。我在 http://svn.rhq-project.org/repos/rhq/branches/HEIKO-EXP/modules/enterprise/server/safe-invoker/src/main/java/org/rhq/enterprise/server/util/HibernateDetachUtility.java 找到一個實用程序,它正是我想要的。它檢查對象並用真實對象替換Hibernate代理。我需要在上述實用程序中自定義以下內容 1.將org.rhq中的classname實例更改爲我的包結構。 2.他們期望pojo身份字段的名稱是「id」。我將其更改爲使用具有javax.persistence.Id註釋的那些屬性。
基本測試與上述更改已完成,它工作正常。我只需要在各種情況下測試整個應用程序,以便它可以在所有情況下工作。
如果我理解你的問題,你正在檢索一個對象A與B有懶關聯。但是,這個關聯沒有被初始化,並且你發現其他模塊拋出了異常,因爲實際上使用了B。所以它在某種程度上需要是。
你想要麼
返回
null
從到B
電話(不可能的,因爲據我所知,除非有這些模塊的一些應用程序特定的行爲,只有你可以知道)或當這樣的呼叫發生時初始化
B
。我會盡力幫助你實現這一個。
爲什麼你得到LazyInitializationExceptions
的原因是,該獲取B
(並沒有初始化)會議已經關閉,所以在這一點上,B
實例是沒有用的,在所有。您可以在此應用的一種解決方法是使用OSIV pattern,以便在所有請求範圍中打開相同的Hibernate會話。這是將會獲取A
與懶惰B
和將會初始化B
當需要會話。 (如果這些異常都在另一個事務的情況下發生的唯一有效的,那就是,與另一個Hibernate會話,從獲取A
的一個不同)
你可以申請另一種選擇是在另一個會話初始化B
。例如:
session.update(a.getB());
當然,你總是可以強制B
初始化與fetchMode.EAGER
或Hibernate.initialize(a.getB())
。但是,無條件地加載實例,即使它根本不會被使用。
此外,你可以找到這個問題的答案可能是有用的:hibernate: LazyInitializationException: could not initialize proxy
其實,你有幾個選項。
1)使A-> B關係EAGER。
2)當您嘗試在休眠會話已關閉時嘗試啓動代理時,您會收到LazyInitializationExceptions
。所以他可能的解決方案是保持Session打開,直到所有的A,B,C ...等對象操作都沒有完成。
3)如果您對WEB環境感興趣,有一種稱爲Open Session的模式。這會使您的Hibernate會話保持打開狀態,直到HTTP請求處於活動狀態。你可以閱讀更多關於here。我認爲這對您閱讀會很有幫助。
當會話關閉時,不要將實體發送到其他模塊。
如果這些其他模塊在與會話相同的應用程序域中執行,請在調用模塊時保持會話打開,並在返回時關閉它。
如果這些模塊不在同一個AppDomain中,如果您需要某種序列化來發送對象,或者如果它是異步調用的,我會使用DTO。暴露服務器之外的實體(我不知道這是否是這種情況)是一個不好的做法,原因有幾個。 Ayende Rahien稱之爲Stripper Pattern。
- 1. 從休眠中的會話中刪除對象?
- 2. 休眠。刪除對象
- 3. 休眠:刪除子對象
- 4. 休眠 - 刪除對象
- 5. 休眠 - 刪除對象引用而不刪除對象
- 6. 休眠刪除對象而不刪除相關對象
- 7. 刪除休眠相關對象和Spring
- 8. 刪除休眠相關對象
- 9. 休眠會話
- 10. 休眠:從合併會話
- 11. 從具有休眠ManyToMany關係的集合中刪除對象
- 12. 休眠刪除
- 13. 休眠不會刪除我的對象。爲什麼?
- 14. [N]休眠會話
- 15. 休眠 - 無法刪除父對象的子對象
- 16. 休眠ManyToMany刪除
- 17. 休眠 - 從集合中刪除項目
- 18. 休眠 - 從@ManyToMany中刪除查詢
- 19. 休眠和從列表中刪除
- 20. 從休眠集合中刪除實體
- 21. 休眠打印會話對象數據列表中的數據
- 22. 獲取休眠中的所有會話緩存對象
- 23. 休眠saveOrUpdate與會話中的另一個對象
- 24. 休眠的EntityManager:如何刪除協會
- 25. 一鍵刪除與onetomany協會休眠
- 26. 休眠:對象已刪除,但仍然可以通過休眠加載
- 27. 從攔截器獲取休眠會話
- 28. 休眠一對多雙向關聯不刪除子對象
- 29. 休眠:從列表中刪除項目不會持續
- 30. 休眠會話工廠Android
我同意將域名暴露給外界不是很好的做法。不幸的是,它是舊代碼,我不能更改方法簽名來使用DTO而不是域。在我的應用程序中,約有98%使用DTO,但導致問題的地方很少。 – dmay