Шаблон для JPA: создание объекта передачи данных DTO из Entity и объединение DTO в базу данных

Я ищу хороший способ создания объектов передачи данных (DTO) из JPA Entity и наоборот. Я хочу отправить DTO как JSON клиенту, затем получить измененный DTO и сохранить его обратно в базу данных. Было бы очень легко выполнить метод слияния из EntityManager на полученном объекте после того, как он был обработан JSON для него классом Java.

Например, существует следующий метод Entity и Rest для сохранения измененного объекта:


@Entity
@Table(name="CUSTOMER")
public class Customer {
    @Id
    Long id;
    @Version
    Long version;
    String name;
    String address;
    String login;
    String password;
    String creditCardNumber;
    @OneToMany(cascade = CascadeType.ALL)
    List<Foo> fooList;

    ... Getter() and Setter()
}

private EntityManager em;
@POST
@Path("/saveCustomer")
public void saveCustomer ( Customer  customer)   {               
   em.merge(customer);
   return;
}  

Это прекрасно работает, пока я отправляю весь Entity Class как JSON и получаю весь Entity. Затем EntityManager объединит модифицированный объект с базой данных. Но когда я хочу только предоставить подмножество Entity (например, только имя и адрес клиента), будут проблемы:

  • Каким будет лучший способ создать подмножество Entity?

    -Написать DTO для Entity вручную? Это создаст повторяющийся код для каждого подмножества объекта, который должен поддерживаться.

  • Как объединить DTO, который является подмножеством Entity, обратно в базу данных?

    -Использование метода merge() для EntityManager не работает. Сначала DTO не является субъектом, поэтому его нельзя объединить. И только создание объекта из DTO будет иметь некоторые неустановленные значения в Entity. После слияния значения будут иметь значение NULL в базе данных.


Одна из идей, которые я придумал, заключалась в том, чтобы указать дополнительные объекты для каждого подмножества, которое я хочу иметь для объекта. (Подобно представлению базы данных) Это будет дублированный код, но он может решить проблему с объединением DTO в базу данных. (И, возможно, этот код может быть сгенерирован автоматически)

Например, Entity CustomerView1 ссылается на ту же таблицу, что и класс Customer, но предоставляет только имя и адрес клиента. Это DTO для реального класса Customer, который может быть отправлен как JSON и изменен вне сервера. Этот класс также может быть объединен с базой данных EntityManager.

@Entity
@Table(name="CUSTOMER")
public class CustomerView1 {
    @Id
    Long id;
    @Version
    Long version;
    String name;
    String address;
    
        ... Getter() and Setter()
}    

Но у меня есть сомнения по поводу этого решения, я не знаю, будет ли это связано с кэшированием объектов JPA для Entities и может вызвать некоторые проблемы.


Мой вопрос: есть ли шаблон для устранения дублирования кода для DTO и слияния DTO обратно в базу данных?

Или есть ли библиотека для этой цели? - Что-то вроде автогенерации для DTO и копирования DTO обратно в реальный Entity, чтобы объединить их с EntityManager.

Ответы

Ответ 1

Если разница в размерах между объектом и DTO незначительна, вы можете выбрать отправку Entity.

При использовании DTO, чтобы преодолеть проблемы concurrency, такие как потерянное обновление, вам необходимо включить версию сущности в ваш DTO.

Если вы не используете версию Entity, а базовая строка будет изменена между методами REST GET и PUT, вы переопределите изменения, о которых конечный пользователь не знал.

Всякий раз, когда мне приходится изменять Entity (Create, Update, Delete), я полагаюсь на механизм

Ответ 2

Взгляните на шаблон дизайна объекта Value, который непосредственно решает вашу проблему.

Этот учебник дает хорошее введение в объекты ценности.

http://www.javastuff.in/2012/04/value-object-pattern.html

Ответ 3

Похоже, что вы описываете именно то, что было сделано для Blaze-Persistence Entity Views. В текущем выпуске поддерживается только создание модели чтения, то есть модели, которую вы отправляете клиенту, но часть модели записи почти завершена. Представление Entity Views отображает представление DTO интерфейса/абстрактного класса и модель сущности. Библиотека использует данные сопоставления настолько хорошо, насколько это возможно, для реализации всех видов оптимизации производительности.