![]() |
Модераторы: LSD, AntonSaburov |
![]() ![]() ![]() |
|
lamao |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 73 Регистрация: 23.4.2008 Репутация: нет Всего: нет |
Есть хибернейт маппинг в XML. Есть Ehcache.
Как можно в таком варианте изменить способ генерации ключей для сущностей в кэше? То есть, чтобы было не com.package.name.Entity#123, а скажем AAA.BBB#CCC. Для чего это нужно. Есть два приложения (пока). Которые должны работать на одной базе. Но вполне может быть, что установлено только одно. У них есть какие-то общие данные. Но! Каждое приложение эти общие данные дополняет своими. Например есть общий com.common.User. В одном приложении у него есть список чего-то там специфического для этого приложения (com.app1.User extends com.common.User). А в другом другой список плюс еще некоторые поля (com.app2.User extends com.common.User). Нужно настроить распределенный кэш. Пока остановились на ehcache + jgroups. Работает все вроде нормально, но эти юзеры в каждом приложении лежат в своем пакете. com.app1.User com.app2.User. Поэтому данные кэшируются под ключами com.app1.User#1 и com.app2.User#1. Соответственно т.к. ключи разные, синхронизироваться они не могут. Если переложить оба класса в пакеты с одинаковым именем, работает все на ура. Но это накладно. Погуглив находил такое для маппинга аннотациями под спринг. Но вот под XML маппинг нету. |
|||
|
||||
COVD |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 4 Всего: 43 |
Если это разные классы, то, наверное, и правильно.
Да, и этот один общий класс следует выделить в отдельную библиотеку и подключить ее ко всем приложениям-участникам распределенного кеша, т.е. всем узлам. Но и при такой архитектуре есть неудобство. При изменениях (рефакторинге) библиотеки придется останавливать все узлы, подкладывать новую версию и запускать все обратно. Это не большая проблема пока узлов всего 2. На мой взгляд удобнее использовать только стандартные классы из JRE для описания обьектов распределенного кеша. Например, Map<String,String>. Или самостоятельно управлять значением serialVersionUID класса, если кеш использует сериализацию для обмена обьектами между узлами. В этом случае есть возможность вносить модификации без одновременного перезапуска всех узлов распределенной системы. Это сообщение отредактировал(а) COVD - 7.5.2012, 17:24 |
||||
|
|||||
lamao |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 73 Регистрация: 23.4.2008 Репутация: нет Всего: нет |
Хм... Я вижу не совсем поняли задачу.
Есть общий класс. Он находится в общей библиотеке. Но каждое приложение расширяет этот свой класс для себя. Например админка добавляет свои поля. А собственно приложение свои. Нужно же, чтобы когда тот же юзер редактируется в админке (меняются ему права например) он удалялся и из кэша основного приложения. Сейчас в качестве ключей используется полное имя класса+id. Нужно же эту генерацию ключей для кэша как-то кастомизировать. Для маппинга в XML. Как такое можно сделать? |
|||
|
||||
COVD |
|
||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 4 Всего: 43 |
Зато я представляю, как работает распределенный кеш ![]()
И обьекты только этого класса и могут быть доступными на всех узлах кеша. Потому что класс общий. Приложение извлекает обьект из кеша и приводит к известному классу ("общему"). Обьект можно редактировать, т.е. менять значения его полей и эти изменения будут доступны другим узлам. Обьект можно удалить. Но как "приложение расширяет этот свой класс для себя" мне непонятно.
Вот "в админке" и надо удалять обьект из распределенного кеша. И когда другое приложение запросит этот обьект из распределенного кеша, оно получит null. Нет "кэша основного приложения", есть один распределенный кеш. Это сообщение отредактировал(а) COVD - 7.5.2012, 22:28 |
||||||
|
|||||||
lamao |
|
||||||||||||||||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 73 Регистрация: 23.4.2008 Репутация: нет Всего: нет |
Я не специалист в кэшах, тем более распределенных. Но все же.... Для организации этого дела используется Ehcache+jgroups. Суть следующая. Каждое приложение имеет свой экземпляр кэша. То есть распределенный кэша это набор узлов, которые взаимодействуют сообщениями. И соответственно тот же юзер будет кэшироваться в каждом кэше. Если в одном приложении мы изменяем поля юзера, то нужно соответствующую запись удалить из кэша. Для этого, через jgroups всем узлам посылается сообщение
Примерно так
Сейчас я обоих этих юзеров поместил в пакет с одним именем. Поэтому ключ для для сохранения в кэше генерируется один.
Но это чревато изменениями во всем проекте, т.к. нужно менять импорты, конфиги. С одной стороны вроде и не сложно, а с другой без этого много лучше. К тому же есть еще несколько сущностей, которые необходимо иметь в распределенном кэше.
Как я уже писал для того, что бы удалить юзера из кэша, нужно послать сообщение всем узлам, что данный по вот такому ключу нужно удалить. Но ключи получаются разные. Вот такие (что не важно затерто). Показан скриншот для каждого узла. ![]() ![]() Нужен способ как изменить генерацию вот этих ключей на свою. Еще нашел в хибернейте в классе CacheKey, который собственно и отвечает по дефолту за генерацию таких ключей, коментарий
и дальше метод
Но почему то у меня судя по всему как раз передается имя не базового класса, а именно сабклассов. |
||||||||||||||||||||
|
|||||||||||||||||||||
COVD |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 4 Всего: 43 |
Для меня неожиданность, что вы вручную строите распределенный кеш из двух разных фреймворков. Есть же много библиотек, где все "в одном флаконе". Например, http://www.hazelcast.com/ . Там все вопросы синхронизации внутри решаются и нет явного "посылания" сообщений через мультикаст. Но суть одна - класс обьекта общий для всех узлов. И, соответственно, единый способ генерации ключа. У вас как я понял два приложения. Приложение А оперирует классом User_A extends User Приложение B оперирует классом User_B extends User Но в распределенный кеш можно положить только обьект User. Только тогда оба приложения могут с ним работать. А дополнительные поля наследников не передаются между узлами. Наверное, надо отказаться от наследования, сделать User member'ом классов User_A и User_B. С другой стороны, у вас на самом деле не распределенный кеш, а два разных кеша, в которых хранятся обьекты разных классов, и вы ищете элегантный способ генерировать общий ключ на основании того, что эти классы - наследники User. Почему надо генерировать ключ, почему нельзя использовать уникальный userID или userEmail, которые наверняка есть в общем классе? |
|||
|
||||
lamao |
|
||||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 73 Регистрация: 23.4.2008 Репутация: нет Всего: нет |
Решил наконец-то эту проблемму.
Еще раз уточню, в чем задача. УЖЕ ЕСТЬ ehcache. Он уже используется для кэширования. На их же сайте есть страница Replicated Caching using JGroups, где, помими прочих вариантов, ими же опысан вариант распределенного кэша с использованием jgroups. Поэтому вариант выглядит довольно нормальным.
Дальше. Да у нас именно такая ситуация. Поля и их значения совершенно не обязательно синхронизировать. Нужно лишь убедиться, что будет отображаться значения, которое в базе. То есть достатотчно просто удалять энтити из кэша, если оно где-то меняется.
Можно. Но это был вопрос топика. Как??? Хибернейт сам генерирует ключ для кэша, используя полное имя класса и его id. Оказывается, если у нас есть иерархия (причем именно хибернейт иерархия - в маппинге), то для ключа будет использоваться имя самого общего предка в маппинге. То есть нужно замапить где-то так
Тогда имя ключа для кэша в обоих приложениях будет com.common.User#1. У нас же был маппинг без наследования (за ненадобностью). Решение, как всегда, простое. |
||||||||
|
|||||||||
![]() ![]() ![]() |
Правила форума "Java" | |
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |