2014-02-28 32 views
3

我正在開發一個項目,該項目要求我們能夠修改ORM實體上的數據,但不能將其保留回數據庫。本質上,我們需要修改對象並將其傳遞給對數據執行一些計算的服務,然後結束請求,但實際上沒有任何數據持久存在。問題在於執行計算的服務確實需要保留一些數據(運行日誌,計算結果)。這意味着一旦過程完成,我們不能只清除整個會話。ColdFusion中的多個Hibernate會話?

我們正在使用的實體相對比較複雜(至少有十幾個關係和更多簡單的屬性),因此在刷新之前從會話中清除實體及其所有相關實體並不是最佳選擇。爲了使事情變得更加困難,執行計算的服務中會有一些ormFlush()調用,這使得手動將實體驅逐到不可能的地方。由於存在大量的關係,所以在我們將它發送給服務之前,急切地加載所有的東西然後逐出它們是不可行的。

由於這些問題,我試圖打開第二個永遠不會被刷新的Hibernate會話(基本上是一個沙箱)。我們可以加載實體並在該會話中進行所需的任何更改,而不必擔心數據庫中存在的更改。

到目前爲止,它已成功,但有一個例外:我無法對實體調用隱式「has」方法(例如hasFoo()hasBar()) - 它會導致NullPointerException。

示例代碼:

ormSession = ormGetSessionFactory().openSession(); 
person = ormSession.load("person", javaCast("int", 123)); 

// assume person has a o2m relationship for "brother" 
writeOutput(person.hasBrother()); 

這將導致以下異常:

java.lang.NullPointerException at 
coldfusion.orm.ImplicitRelationUDF.runHasMethodWithNoArgs(ImplicitRelationUDF.java:410) at 
coldfusion.orm.ImplicitRelationUDF.invoke(ImplicitRelationUDF.java:246) at 
coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:431) at 
coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:414) at 
coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2432) at 
cfsean2ecfm1294924799.runPage(C:\websites\test.cfm:11) 

我的預感是ImplicitRelationUDF.java試圖使用「標準」 CF Hibernate會話和失敗原因這個實體被加載到不同的會話中,但我不知道如何在這一點上進一步研究。

我採取了另一種方法,但仍然無法正常工作,但它(或許)是一種思考。它會拋出與上面的代碼相同的錯誤。

transaction { 
    person = entityLoadByPK("person", 123); 
    transaction action="rollback"; 
} 

writeOutput(person.hasBrother()); 

我願意向特定問題的解決方案(固定有*)或修改一個實體,並確保數據不會持續回DB的更普遍的問題。

+0

你可以嘗試的Application.cfc設置'flushatrequestend = FALSE'。這意味着提交ORM更改的唯一方法是在調用'entitySave()'後手動調用'ORMFlush()'。在需要保存數據的服務中,在完成對這些對象的'entitySave()'調用之後,可以簡單地調用'ORMFlush()'。 –

+0

@ScottStroz當ORM被刷新時 - 通過'flushatrequestend'手動或自動刷新 - 它將持續保持任何持久(例如通過new/entityNew加載而不是通過new/entityNew創建)實體的髒屬性,而不管'entitySave()'調用。 –

+0

廢話....忘了那件事。愚蠢的休眠。 –

回答

0

我知道你正在使用的實體是相對複雜的,但我現在所能想到的是在其中編寫一個克隆方法,並將它所包含的所有內容克隆到不附加到任何會話的新實例中,並使用該克隆實例傳遞給需要orm持久性的服務。

有可能會有更好的解決方案,但如果時間是一個約束,我敢肯定這將工作。

How do you deep clone a persistent entity in ColdFusion ORM?

我很樂意學習如何處理這個與ORM會議,因爲我讀過,它不是在ColdFusion的落實到位。

+0

這是一個可能的解決方案,但我真的很想避免在前面加載所有內容,如果我們要克隆該實體,則需要這樣做。 –

+0

假設你有延遲加載的地方,而不是編寫一個克隆方法並克隆所有的東西,你可以在需要的時候將任何你想要的東西複製到服務層的新實例中。這是可行的,但它很愚蠢。希望一些hibernate會話專家可以給你一個更好的解決方案。 – Henry

2

設置會話默認爲只讀

ormSession = ormGetSessionFactory().openSession(); 
ormSession.setDefaultReadOnly(true); 
person = ormSession.load("person", javaCast("int", 123)); 

你在會議上呼籲任何將只讀

+0

Sam,實體將只能讀取,但我們仍然無法訪問隱式的has *方法。 –