Spring: buen uso de entidades administradas/proxies con ORM
Actualmente estoy pensando en cómo manejo mis objetos de dominio junto con hibernación considerando lo siguiente:
- Mi objeto modelo está anotado directamente con anotación JPA, sin capa de entidad.
- En algunas operaciones pesadas de la base de datos, no me importa ajustar mi código para aprovechar al máximo los proxies, incluso si podemos considerarlo como una fuga de enmascaramiento de abstracción/implementación. Por supuesto que prefiero cuando puedo hacer lo contrario.
- Porque no tengo una capa de entidad, no tengo una capa DAO, el administrador de la entidad se considera a sí mismo como una capa DAO (relacionado: encontré JPA, o similar, no fomente el patrón DAO)
Sin embargo, estaba pensando en mejorar lo que estoy haciendo para reducir un poco la complejidad, o al menos, reubicar esa complejidad en un lugar que encaje mejor, como el servicio relacionado de la entidad. Y quizás más abstracto el hecho de que estoy usando un ORM.
Aquí hay un servicio CRUD genérico del que hereda todo mi servicio empresarial.Este código es para mostrarle cómo se hacen las cosas actualmente (anotación, eliminar registros para mayor claridad):
public void create(T entity) {
this.entityManager.persist(entity);
}
@Transactional(value = TxType.REQUIRED, rollbackOn=NumeroVersionException.class)
public void update(T entity) throws NumeroVersionException{
try{
this.entityManager.merge(entity);
}catch(OptimisticLockException ole){
throw new NumeroVersionException("for entity "+entity, ole);
}
}
public T read(int id) {
return this.entityManager.find(entityClass, id);
}
public void delete(int id) {
T entity = this.entityManager.getReference(entityClass, id);
this.entityManager.remove(entity);
// edit : removed null test thanks to @JBNizet
}
El problema con este tipo de implementación es que si quiero crear un objeto, entonces uso las ventajas de los proxies, básicamente tengo que crearlo y luego recuperarlo. Por supuesto, es posible que la consulta no llegue a la base de datos, sino solo a la memoria caché de Hibernat (aunque no estoy seguro). Pero eso significa que todavía no tengo que olvidar recuperar el proxy.
Esto significa que filtre el hecho de que soy nosotrosing un ORM y proxies detrás de escena.
Así que estaba pensando en cambiar mi interfaz a algo como:
public T read(int id);
public T update(T t)throws NumeroVersionException;
public T create(T object);
public void delete(int id);
List<T> list();
Lo que significa que una vez que pase un objeto a esta capa, tendré que usar el valor devuelto. E implementa actualizaciones específicamente como:
public T update(T t){
if(!(t instanceof [Proxy class goes there])){
//+ check if it is a detached proxy
entityManager.merge(t);
}
}
Dado que merge llega a la base de datos cada vez que se llama, para alguna operación que involucre solo algunas entidades de 10, esto puede ser molesto, no lo llamaría en un método de actualización con un proxy.
Por supuesto que espero tener algunos casos extremosdonde necesitaré el EntityManager para vaciar las cosas y así sucesivamente. Pero creo que esto reduciría significativamente la complejidad actual de mi código y aislaría mejor las preocupaciones.
Lo que intento en resumen es reubicar el código ORM dentro del servicio para poder ocultar el hecho de que estoy usando un ORM y proxies y usar la interfaz como si estuviera usando cualquier otra implementación sin perder los beneficios de utilizando un ORM.
La pregunta es así:
- ¿Es ese nuevo diseño una buena idea?¿Le gusta esta idea?
- ¿Me perdí algo sobre cómo manejar esto correctamente?
Nota: aunque estoy hablando de rendimiento, mi preocupación también es sobre el aislamiento de preocupaciones, la capacidad de mantenimiento y la facilidad de uso para los desarrolladores que no están familiarizados con los ORM y Java con los que trabajo.
------------Respuesta------------
Gracias a @JBNizet, veo algo más claro:
- Debería usar el valor devuelto por el método merge().
- Un mLa entidad administrada no siempre es un proxy.
- No tengo que abstraer el hecho de que uso entidades administradas, esto conducirá a un código complejo e ineficiente
- Elegí JPA, no lo cambiaré, lo cual es cierto a menos que reescriba el modelo completo para representar algo basado en una base de datos no relacional.
Así que simplemente cambiaré mi método de actualización del código original y me quedaré con el resto.
Etiquetas: proxy-classes jpa spring hibernate orm
Artículos relacionados:
ios: incrustación de anuncios en una vista uitable cada "x" células
redes: ¿por qué 802.1Q no encapsula el marco original?
- jquery - ¿Qué hay de malo con este formulario de autocompletar javascript?
- javascript - ¿Cómo definir la precedencia de los cargadores en el paquete web?
- PHP/MySQL: cómo diferenciar la identificación duplicada del bucle anidado
- java: cómo obtener la ruta de un archivo pero sin el nombre real del archivo
- ios10 - iOS 10: seguridad de transporte de Apple "dominios de excepción" ya no funciona
- javascript: restablecer los valores de $ _POST después del envío
- python - paramiko - ¿Cómo puedo actualizar la fecha de modificación de un archivo en el servidor SFTP automáticamente?
- java - Dataflow + Datastore = DatastoreException: error de E/S
- cadena - C ++ - repetidamente usando istringstream
- javascript - AngularJS ui-router guarda el estado anterior
- algoritmo: cómo hacer un triángulo x en python a partir del código fuente a continuación
- java - ¿Por qué las clases como sun.reflect.Reflection no son API públicas?
- javascript: ejecuta la función solo cuando se cargan imágenes/sonidos, Jquery
- rest: datos compartidos conmigo de Onedrive for business access
- python - ¿Cómo organizo una lista anidada que representa valores de coordenadas en una lista de coordenadas?
Artículos calientes
- medicina china para la bronquitis
- Diferencia entre infección de las vías respiratorias superiores y bronquitis
- ¿Qué causa la epididimitis?
- Criterios diagnósticos de cálculos renales
- ¿Qué medicamento la masturbación causa prostatitis?
- ¿Cuáles son los factores de padecer gota?
- Qué comer durante la convalecencia de una hemorragia cerebral
- que es el alzheimer
- Principales criterios diagnósticos de las bronquiectasias
- ¿Cuáles son las formas de prevenir y tratar la menstruación irregular en las mujeres?
- Síntomas de gota de ternera
- Saco gestacional de 5x4mm cuanto dura el embarazo
- La diferencia entre espinillas y espinillas de ácaros
- Por qué frotar con jengibre puede tratar la caída del cabello
- ¿Cuánto tiempo se puede vivir con insuficiencia hepática?