JPA клиент-серверная структура репликации / синхронизации? - PullRequest
1 голос
/ 25 октября 2011

У меня есть простой клиент (JavaSE, Swing) - сервер (Java EE, EJB, JPA).

Я хотел бы создать клиентасторона "кеш" для моих серверных сущностей.Например, если я загружаю сущность, я буду хранить ее во встроенной базе данных Derby (с JPA на стороне клиента), поэтому в следующий раз, когда это потребуется, клиент сначала будет искать в своей собственной базе данных и извлекать сущность оттуда.пощадить сетевое общение.(Простая репликация)

Моя проблема начинается с идентификаторов сущностей: наличие одного и того же идентификатора на стороне клиента и сервера звучит очень плохо, поэтому я должен сохранить некоторое сопоставление для идентификатора стороны клиента и сервераидентификатор стороны объекта.Проблема сохраняется, потому что у меня так много энтузиастов (15 ~ 20 ..) и ассоциаций между ними.

Размещение правильных идентификаторов для связи с сервером (обновление, объединение) или на стороне клиента способствуетнекоторый рекурсивный и, возможно, рефлексивный код, движок, который отслеживает сопоставленные идентификаторы:

  • , если я изменил сущность на стороне клиента и хочу объединиться с сервером перед отправкой на сервер,он должен заменить идентификаторы на стороне клиента в наборе сущностей (в различных внешних ключах @OneToMany)
  • со стороны сервера, проблема в том, что наоборот

Кто-нибудь знает о такомфреймворк, особенно для пользователей JPA?Или у вас есть несколько советов по реализации?// Я хотел бы решить эту проблему на уровне сохраняемости приложений, если это возможно

Заранее спасибо, Андрас Литер

Ответы [ 2 ]

1 голос
/ 25 октября 2011

Что не использовать те же идентификаторы?Похоже, у вас не было бы проблем, если бы вы не пытались иметь другие ...

0 голосов
/ 25 октября 2011

Я недавно кодировал клиента, который должен синхронизировать объекты с сервером, сохраняя их в локальной базе данных Derby.Клиент также может создавать новые объекты, которые должны быть синхронизированы с сервером.Кроме того, и клиент, и сервер использовали одни и те же классы сущностей, компоненты уровня DAO и уровня обслуживания.Я поделюсь проблемой, с которой столкнулся, и своими решениями.Если они актуальны, я надеюсь, что они помогут.

Я использовал одинаковые поля идентификаторов на клиенте и сервере.

Одна из проблем, которую вы МОЖЕТЕ иметь, связана с автоматически генерируемыми ключами.Ключи моего сервера были автоматически сгенерированы в базе данных MS SQL Server.Мои сущности были помечены так:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)

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

Чтобы сделатьДля этого я создал файл orm.xml в клиентском приложении, который позволяет напрямую вводить ключ.orm.xml переопределит аннотации.

См .: Генератор последовательностей в файле persistence.xml

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

Мне нужен был генератор на клиенте, потому что я создавал новые сущности.В этом случае мне нужен был способ генерировать новые ключи и вставлять сущности с сервера.Я использовал Hibernate в качестве поставщика JPA.Это позволило мне создать слушателя, который выяснил, был ли объект новым или уже имел идентификатор.Исходя из этого, я либо позволил генератору создать идентификатор, либо использовал идентификатор, который уже имел сущность.

См .: Стратегия генерации идентификатора JPA

Далее мне нужно былоспособ для сервера узнать, какие объекты являются новыми.По приведенной выше ссылке вы можете видеть, что мой генератор запущен на 100000000. В моем случае это число достаточно велико, потому что у сервера не будет такого высокого идентификатора в течение длительного времени (если вообще когда-либо).Конечно, это не самое чистое решение, и я попытался использовать отрицательное число для всех идентификаторов на клиенте, но Hibernate не смог создать последовательность должным образом из-за ошибки.

См .: JPA / Hibernate / Derby TableGenerator использует отрицательные значения

Итак, на сервере я проверяю все объекты, появляющиеся, если какая-либо из них выше магического числа(100000000), я обнуляю их ID перед сохранением.Таким образом, сервер добавит их как новые, и они получат ID с сервера.Затем они должны быть синхронизированы с клиентом и т. Д.

Надеюсь, это помогло.

...