web-dev-qa-db-fra.com

JPQL Créer un nouvel objet dans l'instruction Select - éviter ou embrasser?

J'ai récemment appris qu'il est possible de créer de nouveaux objets dans les instructions JPQL comme suit:

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

Est-ce quelque chose à éviter ou plutôt à embrasser? Quand l'utilisation de cette fonctionnalité est-elle justifiée à la lumière des bonnes pratiques?

60
mgamer

Ne l'évitez pas , le SELECT NEW est là car il existe des cas d'utilisation parfaitement valides comme le rappelle le §10.2.7.2 . Expressions du constructeur JPQL dans la clause SELECT de la spécification EJB 3.0 JPA :

Un constructeur peut être utilisé dans la liste SELECT pour renvoyer une ou plusieurs instances Java. La classe spécifiée n'est pas requise pour être une entité ni être mappée à la base de données. Le nom du constructeur doit être complet.

Si un nom de classe d'entité est spécifié dans la clause SELECT NEW, les instances d'entité résultantes sont dans le nouvel état.

SELECT NEW com.acme.example.CustomerDetails(c.id, c.status, o.count)
FROM Customer c JOIN c.orders o
WHERE o.count > 100

En bref, utilisez SELECT NEW lorsque vous ne souhaitez pas récupérer une entité complète ou un graphique complet d'objets de manière sécurisée (par opposition à un Object[]). Que vous mappiez le résultat d'une requête dans une classe d'entité ou une classe non mappée dépendra de votre sélection. Un exemple typique serait un écran de liste (où vous pourriez ne pas vouloir tous les détails).

En d'autres termes, ne l'utilisez pas partout mais n'interdisez pas son utilisation (peu de choses ne sont que noires ou blanches).

113
Pascal Thivent

Vous utilisez souvent ce type de requête lorsque vous souhaitez récupérer un Data Transfer Object. Peut-être qu'un rapport peut être un bon endroit pour l'utiliser. Si vous souhaitez simplement récupérer un seul objet de domaine (comme de Family à la place), il n'y a donc aucune raison de l'utiliser.

30
Arthur Ronald

Un objet créé avec new ne doit pas être un DTO, c'est-à-dire un objet qui sera exporté par la couche Business. Il peut également s'agir d'un objet de domaine POJO, c'est-à-dire un objet utilisé en interne par la couche métier.

La raison d'utiliser ce type de POJO en tant qu'objet partiel au lieu de l'entité JPA complète est la performance dans des types spécifiques de JOINS. Une excellente ressource qui explique cela est: http://use-the-index-luke.com/sql/join/hash-join-partial-objects

7
gmournos