Обновление кеша 2-го уровня Hibernate

У меня следующая проблема. Я использую JBoss 5.1, JPA / Hibernate с кешем 2-го уровня. В моей системе несколько объектов, отображающих одну и ту же таблицу базы данных. Пример: Таблица FURNITURES сопоставлена ​​сущностями «Мебель» и «Мебель».

Эти классы НЕ МОГУТ быть изменены.

Теперь, когда я меняю данные «Furn» с идентификатором 1, «Мебель» с идентификатором 1 все еще имеет старые данные. Есть ли возможность выселить «Мебель» после обновления «Фурнитуры»?


person androdevo    schedule 29.10.2012    source источник
comment
На самом деле я думаю, что Hibernate должен делать это автоматически (ошибка?), Поскольку он полностью знает все сущности и таблицы.   -  person Tomasz Nurkiewicz    schedule 29.10.2012
comment
Многие люди предполагают, что спящий режим должен кэшировать необработанные данные вместо сущностей, но листинг кеша содержит сущности, а не кэшированные строки.   -  person androdevo    schedule 29.10.2012


Ответы (2)


Когда вы обновляете / удаляете свой объект, на уровень кэширования отправляется уведомление, чтобы отразить эти изменения.

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

Если вы включите отладку, вы увидите следующую структуру (она может различаться в зависимости от типа вашего постоянного объекта, идентификатора - составного или нет и т. Д.):

cacheKey = {org.hibernate.cache.CacheKey}
|- key = {your.own.serializable.class}
|- type = {org.hibernate.type.ComponentType}
| |- typeScope = {org.hibernate.type.TypeFactory$TypeScopeImpl}
| | |- factory = {org.hibernate.impl.SessionFactoryImpl}
| |- propertyNames = {...}
| |- propertyTypes = {...}
| |- propertyNullability = {...}
| |- propertySpan = 2
| |- cascade = {...}
| |- joinedFetch = {...}
| |- isKey = true
| |- tuplizerMapping = {...}
|- entityOrRoleName = {java.lang.String} "my.Entity"
|- entityMode = {org.hibernate.EntityMode}
|- hashCode = 588688

Как видите, ключ кеша Hibernate хранит информацию об имени класса, типе идентификатора и т. Д. Если у вас есть два разных типа, они будут сопоставлены с двумя разными ключами кеша, следовательно, ваша проблема.

Чтобы исправить это, вы можете создать классы DAO для обеих сущностей и гарантировать, что все вызовы для сохранения этих сущностей проходят только через них и больше нигде. Затем в методе _2 _ / _ 3_ обеих записей просто загружайте и вытесняйте другую сущность.

Другой вариант - использовать перехватчики, которые могут помочь достижение той же функциональности, но, на мой вкус, путь DAO чище.

person mindas    schedule 29.10.2012

Сопоставление одной и той же таблицы с двумя объектами не рекомендуется, поэтому я не думаю, что спящий режим справится с этим автоматически.

Вы можете реализовать прослушиватель после сброса для объекта Furn, а затем использовать что-то вроде приведенного ниже кода, чтобы выселить соответствующий объект Мебель.

// This creates a proxy if not already loaded 
// other gives the object
Furniture furniture = session.load(Furniture.class,furn.getId());
// remove from first level cache
session.evict(furniture);
// remove from second level cache
sessionFactory.evict(Furniture.class,furn.getId());
person gkamal    schedule 29.10.2012
comment
Можете ли вы предоставить документацию, подтверждающую, что спящий режим не может с этим справиться? Я просто хочу быть уверенным. Спасибо за информацию о выселении. Раньше я думал об использовании его с прослушивателем кеша, но я не уверен на 100%, что он надежен. - person androdevo; 29.10.2012