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


У меня есть следующая проблема. Я использую JBoss 5.1, JPA / Hibernate с кэшем 2-го уровня. В моей системе есть несколько сущностей, отображающих одну и ту же таблицу базы данных. Пример: Стол мебель соответствует сущности 'Н' и 'мебель'.

Эти классы не могут быть изменены.

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

2 2

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 для обеих сущностей и гарантировать, что все вызовы для сохранения этих сущностей проходят только через них и нигде больше. Затем, в update/delete Метод обеих записей просто загрузить и выселить другая организация.

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

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

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

// 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());