java - how - spring jpa postgresql example
¿JPA se fusiona en una aplicación web RESTful con DTO y bloqueo optimista? (2)
El uso de Combinación requiere que envíe y reciba una representación completa de la entidad, o que mantenga el estado del lado del servidor. Para operaciones triviales de tipo CRUD-y, es fácil y conveniente. Lo he usado mucho en aplicaciones web sin estado donde no existe un riesgo de seguridad significativo para permitir que el cliente vea a toda la entidad.
Sin embargo, si ya ha reducido las operaciones para pasar solo la información relevante de manera inmediata, también debe escribir manualmente los servicios correspondientes.
Solo recuerde que cuando realice la actualización de su ''DIY'' todavía necesita pasar un número de versión en el DTO y compararlo manualmente con el que sale de la base de datos. De lo contrario, no obtendrá el Bloqueo optimista que abarca el "tiempo de reflexión" del usuario que tendría si estuviera utilizando el enfoque más simple con la combinación.
No puede cambiar la versión en una entidad creada por el proveedor, pero cuando haya creado su propia instancia de la clase de entidad con la
new
palabra clave, está bien y se espera que establezca la versión en ella.Hará que la representación persistente coincida con la representación en memoria que proporciona, esto puede incluir hacer que las cosas sean nulas. Recuerde que cuando se fusiona un objeto, se supone que ese objeto se debe descartar y reemplazar con el que devuelve la fusión. Se supone que no debes fusionar un objeto y luego continuar usándolo. Su estado no está definido por la especificación.
Cierto.
Lo más probable, siempre y cuando su solución de bricolaje también utilice el ID de entidad y no una consulta arbitraria. (Hay otros beneficios de usar el método ''buscar'' sobre una consulta).
Cierto.
Mi pregunta es la siguiente: ¿existe alguna vez un rol para JPA merge
en una aplicación web sin estado?
Hay mucha discusión sobre SO sobre la operación de merge
en JPA. También hay un gran artículo sobre el tema que contrasta la fusión de JPA a través de un proceso más manual de "Hágalo usted mismo" (donde puede encontrar la entidad a través del administrador de la entidad y hacer sus cambios).
Mi aplicación tiene un modelo de dominio enriquecido (diseño basado en dominio ala) que utiliza la anotación @Version
para hacer uso del bloqueo optimista. También hemos creado DTO para enviar por cable como parte de nuestros servicios web RESTful. La creación de esta capa DTO también nos permite enviar al cliente todo lo que necesita y nada que no haga.
Hasta ahora, entiendo que esta es una arquitectura bastante típica. Mi pregunta es sobre los métodos de servicio que necesitan ACTUALIZAR (es decir, HTTP PUT) objetos existentes. En este caso, tenemos estos dos enfoques: 1) Combinación JPA y 2) DIY.
Lo que no entiendo es cómo la fusión JPA puede incluso considerarse una opción para manejar las actualizaciones. Aquí está mi pensamiento y me pregunto si hay algo que no entiendo:
1) Para crear correctamente una entidad JPA separada de un DTO de cable, el número de versión debe configurarse correctamente ... de lo contrario, se lanzará una excepción OptimisticLockException. Pero la especificación JPA dice:
Una entidad puede acceder al estado de su campo de versión o propiedad o exportar un método para que la aplicación lo use, pero no debe modificar el valor de la versión [30]. Solo el proveedor de persistencia tiene permiso para establecer o actualizar el valor del atributo de versión en el objeto.
2) La fusión no maneja las relaciones bidireccionales ... los campos que apuntan hacia atrás siempre terminan como nulos.
3) Si falta algún campo o dato en el DTO (debido a una actualización parcial), la combinación JPA eliminará esas relaciones o anulará esos campos. Hibernate puede manejar actualizaciones parciales, pero no la fusión JPA. DIY puede manejar actualizaciones parciales.
4) Lo primero que hará el método de combinación es consultar la base de datos para obtener el ID de la entidad, por lo que no se obtiene ningún beneficio de rendimiento sobre el bricolaje.
5) En una actualización DYI, cargamos la entidad y hacemos los cambios de acuerdo con la DTO; no hay ninguna llamada para merge
o persist
, porque el contexto JPA implementa el patrón de unidad de trabajo fuera de la caja.
¿Tengo esto derecho?
Editar:
6) El comportamiento de fusión con respecto a las relaciones cargadas perezosas puede diferir entre los proveedores .
Yo podria agregar:
7) Fusionar se traduce para insertar o actualizar dependiendo de la existencia del registro en la base de datos, por lo que no se trata correctamente con la concurrencia optimista de actualización contra eliminación. Es decir, si otro usuario elimina simultáneamente el registro y usted lo actualiza, debe (1) lanzar una excepción de concurrencia ... pero no lo hace, simplemente inserta el registro como uno nuevo.
(1) Al menos, en la mayoría de los casos, en mi opinión, debería ser así. Puedo imaginar algunos casos en los que me gustaría que este caso de uso activara un nuevo inserto, pero están lejos de lo habitual. Al menos, me gustaría que el desarrollador lo piense dos veces, no solo que acepte "merge () == updateWithConcurrencyControl ()", porque no lo es.