Шаблон для 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 интерфейса/абстрактного класса и модель сущности. Библиотека использует данные сопоставления настолько хорошо, насколько это возможно, для реализации всех видов оптимизации производительности.