JPQL Crear nuevo objeto en declaración de selección: ¿evitar o aceptar?
Recientemente aprendí que es posible crear nuevos objetos en JPQL
declaraciones de la siguiente manera:
select new Family(mother, mate, offspr)
from DomesticCat as mother
join mother.mate as mate
left join mother.kittens as offspr
¿Es esto algo que debemos evitar o más bien aceptar? ¿Cuándo se justifica el uso de esta característica a la luz de las buenas prácticas?
No lo evite , SELECT NEW está ahí porque hay casos de uso perfectamente válidos para él, como se recuerda en el §10.2.7.2. Expresiones del constructor JPQL en la cláusula SELECT de la especificación JPA EJB 3.0 :
Se puede utilizar un constructor en la lista SELECT para devolver una o más instancias de Java. No es necesario que la clase especificada sea una entidad ni esté asignada a la base de datos. El nombre del constructor debe estar completamente calificado.
Si se especifica un nombre de clase de entidad en la cláusula SELECT NEW, las instancias de entidad resultantes están en el estado nuevo.
SELECT NEW com.acme.example.CustomerDetails(c.id, c.status, o.count) FROM Customer c JOIN c.orders o WHERE o.count > 100
En resumen, utilice SELECT NEW cuando no desee recuperar una entidad completa o un gráfico completo de objetos de forma segura (a diferencia de un archivo Object[]
). Si asigna el resultado de una consulta en una clase de entidad o en una clase no asignada dependerá de su selección. Un ejemplo típico sería una pantalla de lista (donde es posible que no desee todos los detalles).
En otras palabras, no lo uses en todas partes pero no prohíbas su uso (pocas cosas son solo blancas o negras).
A menudo se utiliza este tipo de consulta cuando se desea recuperar un objeto de transferencia de datos . Quizás un informe pueda ser un buen lugar para utilizarlo. Si solo desea recuperar un único objeto de dominio (como, por ejemplo , de Familia ), no hay razón para usarlo.
Un Objeto creado con new no tiene por qué ser un DTO, es decir, un Objeto que será exportado por la capa Empresarial. También puede ser un objeto de dominio POJO, es decir, un objeto utilizado internamente por la capa empresarial.
La razón para utilizar este tipo de POJO como un Objeto parcial en lugar de la Entidad JPA completa es el rendimiento en tipos específicos de JOINS. Un gran recurso que explica esto es: http://use-the-index-luke.com/sql/join/hash-join-partial-objects