JPQL Créer un nouvel object dans la déclaration de sélection – éviter ou adopter?

J’ai appris récemment qu’il est possible de créer de nouveaux objects 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 à emarmser? Quand l’utilisation de cette fonctionnalité est-elle justifiée à la lumière des bonnes pratiques?

Ne l’évitez pas , le SELECT NEW est là car il y a des cas d’utilisation parfaitement valables comme cela est rappelé dans 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 ne doit pas nécessairement être une entité ou être mappée à la firebase database. Le nom du constructeur doit être entièrement qualifié.

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 résumé, utilisez SELECT NEW lorsque vous ne souhaitez pas récupérer une entité complète ou un graphique complet d’objects de manière sûre (contrairement à 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 sont uniquement en noir ou blanc).

Vous utilisez souvent ce type de requête lorsque vous souhaitez récupérer un object de transfert de données . Peut-être qu’un rapport peut être un bon endroit pour l’utiliser. Si vous voulez juste récupérer un object de domaine unique (comme à la place de la famille ), il n’ya aucune raison de l’utiliser.

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

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