Краткий ответ: Если вы используете подход «Интеграционный уровень», то вещи, которые вы должны интегрировать, должны быть слабо связанными сервисами, следуя принципам SOA.
Это означает, что вы не должны разрешать удаленные вызовы методов для объектов, которые могут выполнять вызовы инфраструктуры под крышкой на другом сервере. Если вы сделаете это, вы действительно создадите тесно связанное распределенное приложение, и вам придется беспокоиться о проблемах с отложенной загрузкой и масштабах контекста персистентности. Если вы хотите этого, вы можете рассмотреть расширенные контексты персистентности http://docs.jboss.org/ejb3/docs/tutorial/extended_pc/extended.html.
Вы говорили о «бизнес-уровне», но JPA не предоставляет бизнес-уровень. Он предоставляет сущности и разрешает операции CRUD, но обычно это не бизнес-операции. операция «RegisterUser» - это не просто вопрос сохранения сущности «пользователь». Уровень DAO может предлагать более высокий уровень работы, но DAO обычно используются для наложения тонкого слоя на базу данных, но он все еще ориентирован на данные.
Лучшим подходом является определение операций типа бизнес-сервисов и предоставление тех сервисов, которые вы предоставляете. Возможно, вам понадобится другой слой поверх вашего DAO или вам может понадобиться один слой (конвертируйте ваш слой DAO).
Ваш бизнес-уровень должен вызывать сброс и обрабатывать любые исключения JPA и скрывать все это от вызывающей стороны.
Вопрос о том, как передавать ваши данные, остается. Во многих случаях параметры ваших запросов бизнес-сервисов будут аналогичны вашим сущностям JPA, но я думаю, вы заметите, что часто есть достаточные различия, которые вы хотите определить новые DTO. Например, бизнес-операция «RegisterUser» может обновить таблицу «User» и «EmailAddresses». Таблица «Пользователь» может содержать свойство «createDate», которое не является частью операции «RegisterUser», но имеет текущую дату.
Для создания DTO вы можете взглянуть на Project Lombok.
Чтобы скопировать DTO для сущности, вы можете использовать Apache Commons BeanUtils (например, PropertyUtils.copyProperties) для выполнения большой части работы, которая работает, если имена свойств совпадают.
Лично я не вижу смысла в XML в этом случае, если только вы не хотите полностью отделить ваши реализации.