Возможно ли иметь удаленно управляемые объекты?

Я не очень хорошо знаком с JPA, но у меня есть такой сценарий: я хотел бы использовать одни и те же классы (читайте «код») как на сервере, так и на клиенте (Java SE) по причинам KISS / DRY. Мне кажется, что один из возможных способов сделать это - иметь (особый?) EntityManager на клиенте, который передает запросы на объекты на сервер и в конце передает все объекты обратно на сервер для "пакетного сохранения действия" где классы могут (повторно) проверять свои данные, применять некоторые транзакционные операции (обновление и прочее), и все они хорошо сохраняются реализацией JPA.

Вопрос в том, возможно ли это? Как? (есть ли уже решение для этого? Это своего рода просто решить эту проблему с помощью "некоторого" кода?)


Изменить: Хорошо, позвольте мне уточнить пару вещей для всех. Мой опыт работы с собственной разработанной платформой приложений, которая использует то, что можно было бы назвать универсальными службами сохранения; то есть службы для выполнения действий CRUD (одна служба на действие для любой таблицы) в рамках одной транзакции, но поддерживаются классами (внутри службы), которые перехватывают эти действия и предлагают проверку и (часто) сложные бизнес-правила (с обновлениями для других таблиц, так далее.). Это было реализовано в более старых продуктах Microsoft. Сейчас происходит переход на .NET, где недавно появились аналогично работающие, но более продвинутые фреймворки, такие как DevForce и CSLA. DevForce, в частности, предлагает то, что я хотел бы сделать и на Java (см. Параграфы «Выполнение на клиенте» в эту страницу, а затем перейдите на эту страницу для лучшего обзора).

Мой более старый вопрос по этой общей теме: Java-эквивалент CSLA


person Doc    schedule 12.08.2011    source источник
comment
И чем это отличается от отправки отсоединенных объектов клиенту, их изменения и последующей отправки обратно на сервер для повторного присоединения и сохранения?   -  person Edwin Dalorzo    schedule 13.08.2011
comment
@edalorzo Я говорю об этом, но ... управление - ключевое слово. Поскольку мои классы поддерживают JPA, было бы здорово иметь EntityManager на клиенте, который имеет добавленную (?) Возможность упаковать все те сущности, с которыми я работал, и отправить их в EntityManager на некоторых сервер, который может правильно позаботиться о постоянстве одним транзакционным махом?   -  person Doc    schedule 14.08.2011
comment
Думаю, я еще не понимаю ваш сценарий. С моей точки зрения, клиент не должен даже знать, что существует такая вещь, как диспетчер сущностей. Правильно представленный через бизнес-интерфейс, сервер мог выполнять всю работу, которую вы предлагаете, за один проход транзакции, когда этого требует клиент, и объекты даже не отказывались бы от безопасности сервера. Когда дело доходит до параллелизма, наличие контекста постоянства для каждого клиента должно быть кошмаром. В зависимости от уровня параллелизма каждый клиент может за очень короткое время стать устаревшим кешем. Вы так не думаете?   -  person Edwin Dalorzo    schedule 16.08.2011


Ответы (2)


Я пробовал делать подобные вещи раньше и, возможно, просто немного поделился своими выводами (в то время я использовал Hibernate + XFire для WS)

Я считаю, что то, о чем вы думаете, работает теоретически. Что вам нужно сделать, это просто сериализовать ваши управляемые объекты и отправить их клиенту. Клиент десериализует и обновляет объект (конечно, на стороне клиента это просто обычный POJO, а не управляемые объекты) и отправляет его обратно на сервер. На этом этапе объект, полученный Сервером, является просто отдельным объектом. Вы можете повторно подключиться к сеансу (JPA / Hibernate выполнит эту оптимистичную проверку параллелизма за вас) и проявить настойчивость.

Однако он отлично работает только для очень простых POJO. Одна из основных проблем заключается в том, что в JPA (или, в основном, во всей структуре ORM) у вас есть отношения между различными объектами. Например, Заказ будет иметь отношения к Продукту и Учетной записи, Учетная запись будет иметь отношение к Клиенту, Клиент будет иметь список адресов ... и т.д. фактически не загружаются, пока вы не получите к нему доступ. Однако, когда вы выполняете сериализацию, это становится трудной проблемой: большинство решений для сериализации, таких как JAXB, просто рекурсивно перемещаются по всем свойствам. В результате вы ожидаете отправить клиентской стороне только объект Order, но, в конце концов, вы отправляете клиенту огромный кусок данных. Простое указание сериализатору не сериализовать некоторые свойства не сработает, потому что, когда объект отправляется обратно и повторно присоединяет отсоединенный obj к сеансу, JPA / Hibernate не имеет возможности узнать, что если вы просто игнорируете отношения или на самом деле удаление отношений. Конечно, есть еще кое-какие уловки, но все это делает такой подход болезненным и уже не элегантным.

person Adrian Shum    schedule 20.02.2013

Ваша идея умная.

Но сделать то, что вы предлагаете, невозможно. Почему нет? Что ж, чтобы ответить на этот вопрос, мы должны сначала понять, «что такое управляемый объект».

Управляемый объект - это не что иное, как «кэшированный» экземпляр. Экземпляр, который находится внутри диспетчера сущностей. Если вы отправляете этот экземпляр по сети на другой компьютер, вы его сериализуете, таким образом копируя его: создавая другой экземпляр на удаленном сервере, который, конечно, не управляется (потому что диспетчер сущностей этого не делает) даже не знаю о его существовании).

С другой стороны, может существовать что-то «достаточно умное», чтобы имитировать диспетчер сущностей и явно «управлять» этой скопированной сущностью, но это выходит за рамки спецификации JPA, и вам придется реализовать это самостоятельно (что, кажется, не расслабьтесь). Не думаю, что для этого есть что-то надежное.

Решением будет сохранение, обновление и т. Д. Явно с вашего клиента (с помощью методов, предоставляемых сервером).

person Mr.Eddart    schedule 13.08.2011
comment
Вы имеете в виду, что я должен предоставить своему клиенту жизненно важные методы EntityManager на сервере? А как насчет сделки? Я видел в примерах, что мне нужно самому контролировать транзакцию: начать транзакцию, сделать свои дела, а затем зафиксировать транзакцию. Я хотел бы заняться своими делами, а затем сказать EntityManager, чтобы он делал все, что требуется для сохранения транзакции автоматически. - person Doc; 14.08.2011
comment
Способ сделать это - предоставить бизнес-сервисы (например, placeBid) с сервера, который выполняется в 1 транзакции, и вы вызываете их, когда поток экрана вашего пользователя завершается. Поддерживать транзакцию, открытую от клиента (что возможно), обычно не является хорошей идеей. Можно поддерживать транзакцию, открытую от клиента, охватывающую несколько вызовов службы, но объекты всегда будут отсоединены при отправке по сети без каких-либо исправлений. - person Mr.Eddart; 14.08.2011