example - mapping dto to entity java
PatrĂ³n para JPA: generar DTO de objeto de transferencia de datos de la entidad y fusionar DTO con la base de datos (3)
Eche un vistazo al patrón de diseño de objetos de valor que aborda directamente su problema.
Este tutorial ofrece una buena introducción a los objetos de valor.
Estoy buscando una buena manera de crear objetos de transferencia de datos (DTO) desde una entidad JPA y viceversa. Quiero enviar el DTO como JSON a un cliente, luego recibir el DTO modificado y guardarlo de nuevo en la base de datos. Sería más fácil realizar el método de combinación desde el EntityManager en el objeto recibido después de que se haya analizado desde JSON a su clase Java.
Por ejemplo, existe la siguiente Entidad y el método Rest para guardar el objeto modificado:
@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;
}
Esto funciona bien siempre y cuando envíe toda la Clase de Entidad como JSON y reciba la Entidad completa de vuelta. Luego, el EntityManager fusionará el objeto modificado con la base de datos. Pero cuando solo quiero proporcionar un subconjunto de la Entidad (como solo el nombre y la dirección del cliente) habrá problemas:
¿Cuál sería la mejor manera de crear un subconjunto de una Entidad?
-Escribiendo a mano los DTOs para la Entidad? Esto generará un código duplicado para cada subconjunto de la entidad, que debe mantenerse.
¿Cómo fusionar un DTO que es un subconjunto de una Entidad, de vuelta a la base de datos?
-Utilizar el método merge () del EntityManager no funciona. Al principio, el DTO no es una entidad, por lo que no se puede fusionar. Y solo creando una Entidad desde el DTO, tendrá algunos valores no configurados en la Entidad. Después de una fusión, los valores serán NULL en la base de datos.
Una idea que se me ocurrió fue especificar entidades adicionales para cada subconjunto que quiero tener para una entidad. (Como una vista de base de datos) Esto sería un código duplicado, pero podría resolver el problema con la fusión del DTO con la base de datos. (Y tal vez este código puede ser generado automáticamente)
Por ejemplo, la Entity CustomerView1 enlaza con la misma tabla que la clase Cliente, pero solo proporciona el nombre y la dirección del cliente. Es un DTO para la clase de Cliente real, que puede enviarse como JSON y modificarse fuera del servidor. Esta clase también puede ser combinada con la base de datos por el EntityManager.
@Entity
@Table(name="CUSTOMER")
public class CustomerView1 {
@Id
Long id;
@Version
Long version;
String name;
String address;
... Getter() and Setter()
}
Pero tengo dudas sobre esta solución, no sé si esto afectará el almacenamiento en caché de las Entidades de la JPA y podría causar algunos problemas.
Mi pregunta es, ¿existe un patrón para resolver la duplicación de código para los DTO y la fusión de los DTO con la base de datos?
¿O hay una biblioteca para este propósito? - Algo, como la generación automática de los DTO y la copia de los DTO a la Entidad real, para que sea posible fusionarlos con el EntityManager.
Si la diferencia de tamaño entre la entidad y el DTO no es considerable, puede optar por enviar la Entidad.
Al usar DTO, para superar problemas de concurrencia como la actualización perdida , debe incorporar la versión de entidad en su DTO.
Si no usa la versión de Entidad, y la fila subyacente se cambia entre los métodos REST GET y PUT, anulará los cambios de los que el usuario final no estaba realmente al tanto.
Cada vez que tengo que modificar una Entidad (Crear, Actualizar, Eliminar), confío en la JPA y el mecanismo de bloqueo optimista de Hibernate .
Para las listas de UI, tablas, resultados de búsqueda, los DTO son una opción viable, ya que solo está interesado en una proyección de su entidad de origen. De esta manera usted acelera las recuperaciones y puede beneficiarse de otras características de SQL (funciones de ventana) que no son compatibles con JPA.
Suena como lo que estás describiendo es exactamente para lo que se han creado las vistas de entidad de persistencia Blaze . La versión actual solo tiene soporte para crear el modelo de lectura, es decir, el modelo que está enviando al cliente, pero la parte del modelo de escritura está casi terminada. Las vistas de entidad se asignan entre una representación DTO de interfaz / clase abstracta y el modelo de entidad. La biblioteca aprovecha la información de mapeo tan bien como puede para implementar todo tipo de optimizaciones de rendimiento.