Bonjour,
j'ai rencontré un problème étrange, même si j'ai pu le contourner.
ma question c'est de savoir, si je m'y suis mal pris et qu'il y a une bonne manière de le faire, si j'ai découvert un bug, ou simplement une évolution à proposer ?
je peux pas donner le code (qui tourne sinon en évitant le bug/faiblesse), mais voici le principe :
j'ai deux entités et une relation many-to-many simple.
la première entité représente une spécialité SpecBean
La deuxième entité est une classe dérivée ProfBean de la base PersoBean.
(un id et pas de relation inverse)
l'héritage est mappé avec un discriminator, et subclass avec un join.
Entre les deux entités prof et spec il y a une relation N-N avec une table, A_POUR_SPECS indiquant les spécialités des profs.
il y a aussi une relation many-to-one, mais ca marche bien, donc je l'indique pas...
le mapping est un truc du style (noms changé, donc ya peut être un bug, mais le vrai mapping marche bien lui):
Code:
<class name="SpecBean"
table="SPEC">
<id name="idSpec" type="long">
<column name="ID_SPEC" precision="18" scale="0" />
<generator class="sequence">
<param name="sequence">S_SPEC</param>
</generator>
</id>
<property name="libelle" type="string">
<column name="LIBELLE" />
</property>
</class>
<class name="PersoBean"
table="PERSO">
<id name="idPerso" type="long">
<column name="ID_PERSO" precision="18" scale="0" />
<generator class="sequence">
<param name="sequence">S_TA_PERSO</param>
</generator>
</id>
<discriminator column="TYPE_PERSO" type="string" />
</class>
<subclass name="ProfBean"extends="PersoBean"
discriminator-value="PROF">
<set name="specs" table="A_POUR_SPECS">
<key>
<column name="ID_PS_ES" precision="18" scale="0" not-null="true" />
</key>
<many-to-many class="SpecBean" column="ID_SPEC" />
</set>
<join table="PROF">
<key>
<column name="ID_PS_ES" precision="18" scale="0" not-null="true" />
</key>
<property name="nom" type="string">
<column name="NOM" />
</property>
</join>
</subclass>
maintenant je veux faire une requête de recherche complexe avec Criteria et notamment filtrer sur une spécialité particulière
je voulais juste récupérer les profs dont une des spec correspondait a l'objet que j'avais en main. ma première tentative a été surprenante:
Code:
Criteria criteria = hConnection.createCriteria(ProfBean.class);
criteria.createAlias("specs","specs");
criteria.add(Restrictions.eq("specs", specialite));
...
criteria.setMaxResults(...);
criteria.list(); ...
j'ai eu un
"ORA-01008: toutes les variables ne sont pas liées"
effectivement la requête est pathologique .j'ai vu passer celà (ici c'est ma vrai requete, mais vous reconnaitrez la structure avec le filtrage sur statut qui est en plus)
en gras, il fait un filtrace incompréfensible sur la clé primaire de la table de la classe de base (ta_acteur)...
Quote:
select * from ( select this_.ID_ACTEUR as ID1_1_, this_.LIBELLE_ACTEUR as LIBELLE3_1_1_, this_1_.ID_STATUT_PS as ID2_3_1_, this_1_.NOM_PS_ES as NOM3_3_1_, this_1_.PRENOM_PS_ES as PRENOM4_3_1_, specialite3_.ID_PS_ES as ID1_, specialite1_.ID_SPECIALITE_PS as ID2_, specialite1_.ID_SPECIALITE_PS as ID1_0_, specialite1_.LIBELLE_SPECIALITE_PS as LIBELLE2_12_0_, specialite1_.CODE_SPECIALITE_PS as CODE3_12_0_ from TESTDMP.TA_ACTEUR this_ inner join TESTDMP.TA_PS_ES this_1_ on this_.ID_ACTEUR=this_1_.ID_PS_ES inner join TESTDMP.TA_A_POUR_SPECIALITES specialite3_ on this_.ID_ACTEUR=specialite3_.ID_PS_ES inner join TESTDMP.TA_SPECIALITE_PS specialite1_ on specialite3_.ID_SPECIALITE_PS=specialite1_.ID_SPECIALITE_PS where this_.TYPE_ACTEUR='PSE' and this_.ID_ACTEUR=? and this_1_.ID_STATUT_PS=? order by this_1_.NOM_PS_ES asc, this_1_.PRENOM_PS_ES asc ) where rownum <= ?
sinon j'ai essayé d'autres trucs
Code:
Criteria criteria = hConnection.createCriteria(ProfBean.class);
criteria.createAlias("specs","s");
criteria.add(Restrictions.eq("s", specialite));
...
... criteria.list(); ...
là il trouve pas le champs"s"
Code:
Criteria criteria = hConnection.createCriteria(ProfBean.class);
criteria.createAlias("specs","s");
criteria.add(Restrictions.eq("s.this", specialite));
...
... criteria.list(); ...
là il trouve pas le champs"s.this"
Code:
Criteria criteria = hConnection.createCriteria(ProfBean.class);
Criteria sub=criteria.createCriteria("specs");
sub.add(Restrictions.eq("this", specialite));
...
... criteria.list(); ...
là il trouve pas le champs"this" (contenu de ROOT_ALIAS)
finalement j'ai réussi à faire marcher en passant par une clé de l'objet explicitement utilisée
Code:
Criteria criteria = hConnection.createCriteria(ProfBean.class);
Criteria sub=criteria.createCriteria("specs");
sub.add(Restrictions.eq("idSpec", specialite.getIdSpec()));
...
... criteria.list(); ...
ca marche aussi pareil avec alias
Code:
Criteria criteria = hConnection.createCriteria(ProfBean.class);
criteria.createAlias("specs","s");
criteria.add(Restrictions.eq("s.idSpec", specialite.getIdSpec()));
...
... criteria.list(); ...
ca marche mais je suis obligé d'exposer le nom de ma clé primaire (qui justement est candidate à évolution... passage d'id à code)...
c'est pas la mort ici, mais ce serait tellement plus jolis si on pouvait comparer uniquement des Bean comme avec les relation many to one...
qui aurait des avis ou infos là dessus...
peut être faudrait t'il que je remonte un bug-report/evolution ?