2010-05-18 53 views
3

假設我有以下的域類映射到傳統的表,利用只讀第二級高速緩存,以及具有瞬態場:的Grails/GORM,禁用第一級高速緩存

class DomainObject { 
static def transients = ['userId'] 

Long id 
Long userId 

static mapping = { 
    cache usage: 'read-only' 
    table 'SOME_TABLE' 
} 
} 

我有一個問題,對DomainObject的引用由於第一級緩存而被共享,因此瞬態字段正在彼此寫入。例如,

def r1 = DomainObject.get(1) 
r1.userId = 22 

def r2 = DomainObject.get(1) 
r2.userId = 34 

assert r1.userId == 34 

也就是說,r1和r2是對同一個實例的引用。這是不可取的,我想緩存表數據而不共享引用。有任何想法嗎?

[編輯]

瞭解的情況現在好了,我相信我的問題可以歸結爲以下幾點:反正有禁用特定域類一級緩存,同時還利用二級緩存?

[編輯]

由於似乎沒有乾淨的方式來獲得這個目的,我們選擇,而不是重新設計周圍需要它。

回答

2

請忽略我之前的回答,我完全不瞭解您的問題。

但是,下面的工作(代碼測試):

def r1 = DomainObject.get(1) 
r1.userId = 22 
r1.discard() //BE CAREFUL WITH THIS, YOU MIGHT END UP WITH a LazyInitializationException 

def r2 = DomainObject.get(1) 
r2.userId = 34 

assert r1.userId == 22 
+0

謝謝。雖然這對我的簡單示例有效,但在整個應用程序中採用這種方法並不實用。令我驚訝的是:Grails的權威指南p.266和p.276確認實例重用是第一級緩存的一部分,但不考慮我提供的場景。我想知道是否有一種方法可以關閉特定域對象的一級緩存,也許這就是問題所在,二級緩存將以我想要的方式工作。 – 2010-05-18 21:41:04

+0

我不知道你的全部要求,所以我不能真正幫助,除了從我的答案這個小例子。這就是說,即使這個例子對我來說似乎很奇怪...... – fabien7474 2010-05-18 22:09:53

+0

這裏的想法可以與一個多元集合相比較(通過瞬態場)並轉換成一個正常集合:例如, [apple,apple,apple,orange,orange] - > [apple',apple'',apple''',orange',orange''] – 2010-05-18 23:16:52

0

我想你可以,處於引導,元類上,可以做一個新的get()方法(或任何其它名稱的方法)相同 - 調用原始的get()並丟棄該對象。

什麼是您的使用場景,需要瞬態字段不共享?您可以隨時爲每個使用位置獲取新的Hibernate會話。 Hibernate會話維護第一級緩存。

+0

謝謝約翰。這是一個好主意,但我無法實現它:def oldGet = SomeDomain。 &get; SomeDomain.metaClass.'static'= {id - > def sd = oldGet(id); sd.discard(); SD};導致了一個stackoverflow,我不知道爲什麼。至於使用場景,我描述它的能力在下降,因爲我們決定圍繞它進行重新設計,這可能是最好的選擇,因爲它顯然違背了GORM的設計。 – 2010-05-22 14:27:16

0

您可以使用DomainObject.findById(1)而不是DomainObject.get(1)。由於「獲取」方法緩存的查詢結果,但前者不。

+0

嗯,我期待這個好主意的工作,但發現DomainObject.findById(1).is(DomainObject.findById(1))爲true。 – 2010-06-16 21:28:50