2010-05-18 3 views
3

Пусть у меня есть следующее отображение домена класса к унаследованной таблице, используя кэш только для чтения второго уровня, и имеющий переходное поле:Grails/Горм, Cache Disable первого уровня

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

Спасибо. Хотя это работает для моего простого примера, это не практический подход, который можно использовать во всем приложении. Я удивлен: стр.266 и стр.276 в «Окончательном руководстве». Grails подтверждает повторное использование экземпляра экземпляра в качестве части кеша первого уровня, но не учитывает сценарий, который я представил. Интересно, есть ли способ отключить кеш первого уровня для определенного объекта домена, возможно, это проблема, и кеш второго уровня будет работать так, как я хочу. –

+0

Я не знаю всех ваших требований, поэтому я не могу помочь, кроме как из моего ответа для этого небольшого примера. Тем не менее, даже пример кажется мне странным ... – fabien7474

+0

Идею здесь можно сравнить с мультисети, которая дополняется (через переходные поля) и преобразуется в нормальный набор: например, [apple, apple, apple, orange, orange] -> [apple ', apple' ', apple' '', orange ', orange' '] –

0

Я полагаю, вы могли бы, в Bootstrap, метакласса на новом ГЭТ() метод (или метод любым другим именем), которые могли бы сделать то же самое - вызовите оригинал get() и отбросьте объект.

Каков ваш сценарий использования, который требует, чтобы временные поля не были доступны? Вы всегда можете получить новую сессию Hibernate для каждого из мест использования. В сеансе Hibernate поддерживается кеш первого уровня.

+0

Спасибо, Джон. Это хорошая идея, но я не мог заставить ее работать: def oldGet = SomeDomain. &get; SomeDomain.metaClass.'static '= {id -> def sd = oldGet (id); sd.discard(); сд}; привели к потоку stackoverflow, я не уверен, почему. Что касается сценария использования, моя способность описать его ослабевает, так как мы решили перепроектировать его, что, вероятно, лучше всего делать, поскольку это явно противоречит тому, как разрабатывается GORM. –

0

Вы можете использовать DomainObject.findById (1) вместо DomainObject.get (1). Поскольку «get» метод кэширует результат запроса, а первый - нет.

+0

Хм, я ожидал, что эта хорошая идея будет работать, но нашла DomainObject.findById (1) .is (DomainObject.findById (1)), чтобы быть правдой. –

 Смежные вопросы

  • Нет связанных вопросов^_^