Bonjour à tous.

Je souhaiterais restreindre le nombre de colonnes ramenées par un select, ce qui en soi ne semble pas monstrueux...

J'ai une hiérarchie d'objet qui ressemble à ça :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
Objet1
String propriété1
String propriété2
Objet2 propriété3
Set<Objet3> propriété4

Objet2
String propriété1Objet2

Objet3
String propriété1Objet3
Les projections fonctionnent parfaitement, tant que je ne veux pas mapper les résultats dans un objet (Objet1).
J'obtiens donc une liste de tableaux d'Object contenant toutes les propriétés que j'ai projetées.

Sauf que j'aimerais vivement pouvoir récupérer une liste d'Objet1, Objet1 sur lequel j'ai créé le Criteria.
Voici la requête :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
 
Criteria vCriteria = (Criteria) getSession().createCriteria(Objet1.class, "aliasPrincipal");
vCriteria.createAlias("aliasPrincipal.propriété3", "aliasSurObjet2");
vCriteria.createAlias("aliasPrincipal.propriété4", "aliasSurObjet3");
ProjectionList vProjections = Projections.projectionList();
vProjections.add(Projections.property("aliasPrincipal.propriété1"), "propriété1");
vProjections.add(Projections.property("aliasPrincipal.propriété2"), "propriété2");
vProjections.add(Projections.property("aliasSurObjet2.propriété1Objet2"), "propriété1Objet2");
vProjections.add(Projections.property("aliasSurObjet3.propriété1Objet3"), "propriété1Objet3");
vCriteria.setProjection(vProjections);
vCriteria.setResultTransformer(new AliasToBeanResultTransformer(Objet1.class));
List<Objet1> vListe = vCriteria.list();
A l'exécution de cette requête, j'obtiens une org.hibernate.PropertyNotFoundException me disant qu'il ne trouve pas le setter de la propriété "propriété1Objet2" dans l'Objet1 (normal, le setter est dans l'Objet2). J'ai beau préfixer la propriété par "aliasSurObjet2", il essaye de récupérer le setter "setPropriété1Objet2" de l'Objet1 et pas de l'Objet2.

Du coup, étant donné que AliasToBeanResultTransformer essaye d'injecter les résultats propriété par propriété (à l'aide des setter) (enfin c'est ce que j'ai cru comprendre), j'ai ajouté la projection suivante :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
vProjections.add(Projections.property("aliasPrincipal.propriété3"), "propriété3");
juste avant la projection :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
vProjections.add(Projections.property("aliasSurObjet2.propriété1Objet2"), "propriété1Objet2");
qui est censée accéder au setter de l'Objet2.

En ajoutant cette projection, je n'ai plus d'erreur. La requête générée est bonne :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
select
    tab1.propriété1,
    tab1.propriété2,
    tab2.propriété1Objet2,
    tab3.propriété1Objet3
from
    table_dObjet1 tab1
inner join
    table_dObjet2 tab2
        on tab2.id = tab1.id
inner join
    table_dObjet3 tab3
        on tab3.id = tab1.id
L'objet Objet2 a bien été instancié mais il est vide. Au moment d'accéder à la propriété propriété1Objet2, Hibernate relance un select * sur Objet2 pour pouvoir l'afficher. C'est le 1er problème.

Je pourrais m'arrêter là, après tout ça fonctionne, j'ai bien réussi à diminuer le nombre de colonnes ramenées par ma requête. A cause du lazy-loading, j'ai certes une requête qui est lancée derrière pour charger une association mais ça fonctionne.

Ca fonctionne, mais pas tout à fait quand même..
Histoire d'en remettre une couche, je n'arrive absolument pas à accéder à la propriété4 (des Objet3), qui elle est une collection.
Là, quasiment le même constat, en ajoutant une projection :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
vProjections.add(Projections.property("aliasPrincipal.propriété4"), "propriété4");
J'obtiens des Objet1 avec une collection d'Objet3 instanciée, mais vide. Et là, dès que j'ajoute une projection derrière :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
vProjections.add(Projections.property("aliasSurObjet3.propriété1Objet3"), "propriété4");
pour essayer d'accéder à une propriété de l'Objet3, même exception.

La conclusion que j'en ai tirée ,c'est que le ResultTransformer ne tient pas compte des alias.

Quelqu'un a-t-il déjà rencontré ce problème? Et éventuellement trouvé une solution...?

A première vue, j'en vois une de solution, c'est abandonner le ResultTransformer et mapper les résultats à la main dans mon Objet1. Si vous avez une solution pas trop couteuse pour faire ça (couteuse en temps), je suis toujours preneur...

Merci à vous!