Liste avec seulement quelques colonnes dans Hibernate
Les outils d’ORM (Hibernate, Ibatis, …) sont aujourd’hui à maturité et ne souffrent plus des problèmes de performance des premières versions. Le code SQL généré, ainsi que la transformation en objets, ont été très largement optimisés.
Cependant selon la taille de la grappe d’objet remontée, il peut subsister des problèmes de performance, liés au nombre et à la complexité des objets à créer. Le cas d’utilisation typique sur une application de gestion est l’affichage d’une liste d’objet complexe sur un écran de recherche.
Prenons le cas par exemple d’une liste de commande (que nous simplifions volontairement) :
[pastacode lang=”java” message=”” highlight=”” provider=”manual”]
public Class Commande {
private Destination destination;
private Set<LigneCommande> lignes;
private Client client;
...
}
[/pastacode]
[pastacode lang=”java” message=”” highlight=”” provider=”manual”]
DetachedCriteria criteria = DetachedCriteria.forClass(Commande.class,"commande")
.createAlias("commande.Destination", "destination", CriteriaSpecification.LEFT_JOIN)
.createAlias("commande.Lignes", "lignes", CriteriaSpecification.LEFT_JOIN)
.createAlias("commande.Client", "client", CriteriaSpecification.INNER_JOIN);
List<Commande> listCommande = getHibernateTemplate().findByCriteria(criteria);
[/pastacode]
Depuis la version 3 d’Hibernate a été introduite la notion de Projection. Celle-ci va nous permettre non seulement de remonter seulement les colonnes qui nous intéressent mais également une liste d’objets non gérés par Hibernate ; par exemple nous allons pouvoir remonter directement une liste de DTO (data transfert object) en se basant sur le même objet criteria (forClass(Commande.class,”commande”)) :
On définit le DTO :
[pastacode lang=”java” message=”” highlight=”” provider=”manual”]
public class DealListDto implements Serializable {
private static final long serialVersionUID = 1L;
private java.lang.String id;
private String ref;
private Date date;
private String nom;
private String prenom;
private String destNom;
...
}
[/pastacode]
[pastacode lang=”java” message=”” highlight=”” provider=”manual”]
criteria.setProjection(Projections.projectionList()
.add(Property.forName("commande.Id"), "id")
.add(Property.forName("commande.Ref"), "ref")
.add(Property.forName("commande.Date"), "date")
.add(Property.forName("client.Nom"), "nom")
.add(Property.forName("client.Prenom"), "prenom")
.add(Property.forName("destination.nom"), "destNom")
.setResultTransformer( Transformers.aliasToBean(DealListDto.class));
List<DealListDto> listCommande = getHibernateTemplate().findByCriteria(criteria);
[/pastacode]