2010-03-01 11 views
53

que he aprendido recientemente que es posible crear nuevos objetos en JPQL declaraciones de la siguiente manera:JPQL Crear nuevo objeto en la instrucción Select - ¿evitar o abrazar?

select new Family(mother, mate, offspr) 
from DomesticCat as mother 
    join mother.mate as mate 
    left join mother.kittens as offspr 

¿Esto es algo que debe evitarse o más bien a abrazar? ¿Cuándo se justifica el uso de esta característica a la luz de las buenas prácticas?

Respuesta

91

No lo evite, el SELECCIONAR NUEVO está allí porque hay casos de uso perfectamente válidos para él como se recuerda en el §10.2.7.2. JPQL Constructor expresiones en la cláusula SELECT del EJB 3.0 JPA Specification:

Un constructor se puede utilizar en la lista SELECT devolver uno o más de Java casos. La clase especificada no es requerida para ser una entidad o ser mapeada en la base de datos. El nombre del constructor debe ser totalmente calificado.

Si se especifica un nombre de clase de entidad en la nueva cláusula SELECT, los instancias de entidad resultantes son en el nuevo estado .

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 NUEVO cuando no se desea recuperar una entidad completa o un gráfico lleno de objetos de una manera segura tipo (en contraposición a un Object[]). Si mapea el resultado de una consulta en una clase de entidad o 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 use en todas partes, pero no prohíba su uso (algunas cosas son solo negras o blancas).

+0

Quiero hacer lo mismo, pero en mi consulta tengo algunas referencias de juntar y jpa: 'la consulta especificó la recuperación de uniones, pero el propietario de la asociación obtenida no estaba presente en la lista de selección'. Triste ... –

+1

Por favor, edite su respuesta y haga que "El nombre del constructor debe estar completamente calificado" en negrita ... es muy importante y una fuente común de errores. –

+1

La respuesta es totalmente correcta, pero el documento vinculado no coincide con la respuesta. Debería ser http://jcp.org/aboutJava/communityprocess/final/jsr317/index.html – Pumuckline

24

A menudo utiliza este tipo de consulta cuando desea recuperar un objeto de transferencia de datos . Tal vez un informe puede ser un buen lugar para usarlo. Si solo desea recuperar un solo objeto de dominio (como en su familia), entonces no hay razón para usarlo.

+3

+1 por mencionar DTOs - exactamente mi caso de uso –

+1

Buen punto, pero ¿cree que el Repositorio debería devolver los DTO y no las entidades? Estoy convirtiendo los objetos en la capa de servicio normalmente, en Repositorio no es demasiado temprano? – Mejmo

5

Un objeto creado con nuevo no tiene que 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 usar este tipo de POJO como objeto parcial en lugar de la entidad JPA completa es el rendimiento en tipos específicos de UNIONES. Un gran recurso que explica esto es: http://use-the-index-luke.com/sql/join/hash-join-partial-objects

Cuestiones relacionadas