Hibernate Requête Par l'Exemple et les Projections

pour faire court: hibernate ne supporte pas les projections et les requêtes par exemple? J'ai trouvé ce post:

le code est le suivant:

User usr = new User();
usr.setCity = 'TEST';
getCurrentSession().createCriteria(User.class)
.setProjection( Projections.distinct( Projections.projectionList()
.add( Projections.property("name"), "name")
.add( Projections.property("city"), "city")))
.add( Example.create(usr))

comme l'a dit l'autre poster, le sql généré continue d'avoir une classe où se référant à juste y0_= ? au lieu de this_.ville .

j'ai déjà essayé plusieurs approches, et j'ai cherché le tracker de problème mais n'ai rien trouvé à ce sujet.

I même essayé D'utiliser Projection alias et Transformers, mais il ne fonctionne pas:

User usr = new User();
usr.setCity = 'TEST';
getCurrentSession().createCriteria(User.class)
.setProjection( Projections.distinct( Projections.projectionList()
.add( Projections.property("name"), "name")
.add( Projections.property("city"), "city")))
.add( Example.create(usr)).setResultTransformer(Transformers.aliasToBean(User.class));

Quelqu'un a-t-il utilisé des projections et des requêtes par exemple ?

21
demandé sur Ryan Cook 2008-09-17 19:40:33

6 réponses

puis-je voir votre classe D'utilisateurs? Ceci est juste en utilisant des restrictions ci-dessous. Je ne vois pas pourquoi les Restrictions seraient vraiment différentes des exemples (je pense que les champs null sont ignorés par défaut dans examples).

getCurrentSession().createCriteria(User.class)
.setProjection( Projections.distinct( Projections.projectionList()
.add( Projections.property("name"), "name")
.add( Projections.property("city"), "city")))
.add( Restrictions.eq("city", "TEST")))
.setResultTransformer(Transformers.aliasToBean(User.class))
.list();

Je n'ai jamais utilisé l'alaistToBean, mais je viens de le lire. Vous pouvez également simplement faire une boucle sur les résultats..

List<Object> rows = criteria.list();
for(Object r: rows){
  Object[] row = (Object[]) r;
  Type t = ((<Type>) row[0]);
}

si vous devez, vous pouvez peupler manuellement L'utilisateur de cette façon.

, Son genre de dur à examiner la question sans plus d'informations pour diagnostiquer le problème.

16
répondu Arthur Thomas 2008-09-17 19:45:24

le problème semble se produire lorsque vous avez un alias du même nom que la propriété objects. Hibernate semble prendre l'alias et l'utiliser dans le sql. J'ai trouvé ceci documenté ici et ici , et je crois que c'est un bug en hibernation, bien que je ne suis pas sûr que l'équipe D'hibernation est d'accord.

de toute façon, j'ai trouvé un travail simple autour qui fonctionne dans mon cas. Votre kilométrage peut varier. Les détails sont ci-dessous, je essayé de simplifier le code de cet exemple donc je m'excuse pour les éventuelles erreurs ou de fautes de frappe:

Criteria criteria = session.createCriteria(MyClass.class)
    .setProjection(Projections.projectionList()
        .add(Projections.property("sectionHeader"), "sectionHeader")
        .add(Projections.property("subSectionHeader"), "subSectionHeader")
        .add(Projections.property("sectionNumber"), "sectionNumber"))
    .add(Restrictions.ilike("sectionHeader", sectionHeaderVar)) // <- Problem!
    .setResultTransformer(Transformers.aliasToBean(MyDTO.class));

Serait de produire ce sql:

select
    this_.SECTION_HEADER as y1_,
    this_.SUB_SECTION_HEADER as y2_,
    this_.SECTION_NUMBER as y3_,
from
    MY_TABLE this_ 
where
    ( lower(y1_) like ? ) 

Qui a été la cause d'une erreur: de java.sql.SQLException: ORA-00904: "Y1_": identifiant invalide

Mais, quand j'ai changé ma restriction à l'utilisation de "ce", comme suit:

Criteria criteria = session.createCriteria(MyClass.class)
    .setProjection(Projections.projectionList()
        .add(Projections.property("sectionHeader"), "sectionHeader")
        .add(Projections.property("subSectionHeader"), "subSectionHeader")
        .add(Projections.property("sectionNumber"), "sectionNumber"))
    .add(Restrictions.ilike("this.sectionHeader", sectionHeaderVar)) // <- Problem Solved!
    .setResultTransformer(Transformers.aliasToBean(MyDTO.class));

Il a la suite sql et mon problème a été résolu.

select
    this_.SECTION_HEADER as y1_,
    this_.SUB_SECTION_HEADER as y2_,
    this_.SECTION_NUMBER as y3_,
from
    MY_TABLE this_ 
where
    ( lower(this_.SECTION_HEADER) like ? ) 

c'est, c'! Une solution assez simple à un problème douloureux. Je ne sais pas comment ce correctif serait traduit la requête par exemple de problème, mais il peut vous rapprocher.

44
répondu Ryan Cook 2010-11-22 19:18:36

le vrai problème ici est qu'il y a un bug dans hibernate où il utilise les alias de la liste de sélection dans la clause où:

http://opensource.atlassian.com/projects/hibernate/browse/HHH-817

Juste au cas où quelqu'un débarque ici à la recherche de réponses, allez voir le billet. Il a fallu 5 ans pour réparer, mais en théorie, ce sera dans l'une des prochaines versions et je soupçonne que votre problème disparaîtra.

6
répondu Dobes Vandermeer 2010-09-15 17:42:46

je suis confronté à un problème similaire. Je suis à l'aide de la Requête par l'Exemple et je veux trier les résultats par un champ personnalisé. En SQL, je voudrais faire quelque chose comme:

select pageNo, abs(pageNo - 434) as diff
from relA
where year = 2009
order by diff

Cela fonctionne très bien sans la commande par article. Ce que j'ai est

Criteria crit = getSession().createCriteria(Entity.class);
crit.add(exampleObject);
ProjectionList pl = Projections.projectionList();
pl.add( Projections.property("id") );
pl.add(Projections.sqlProjection("abs(`pageNo`-"+pageNo+") as diff", new String[] {"diff"}, types ));
crit.setProjection(pl);

Mais quand j'ajoute

crit.addOrder(Order.asc("diff"));

je org.mise en veille prolongée.QueryException: impossible de résoudre la propriété: diff l'exception". Solution de contournement avec ce ne fonctionne pas non plus.

PS: comme je n'ai pas pu trouver de documentation élaborée sur L'utilisation du QBE pour L'hibernation, tout ce qui est ci-dessus est principalement une approche d'essai et d'erreur

0
répondu VHristov 2009-06-10 16:07:38
ProjectionList pl = Projections.projectionList();
pl.add(Projections.property("id"));
pl.add(Projections.sqlProjection("abs(`pageNo`-" + pageNo + ") as diff", new String[] {"diff"}, types ), diff); ---- solution
crit.addOrder(Order.asc("diff"));
crit.setProjection(pl);
0
répondu singh 2016-02-13 15:16:48

je ne pense pas vraiment que donc, ce que je trouve, c'est le mot "cela". les causes de la veille prolongée de ne pas inclure toutes les restrictions à sa requête, ce qui signifie qu'il a obtenu tous les enregistrements de listes. À propos de la veille prolongée bug qui a été rapporté, je peux voir qu'il est signalé comme étant fixe, mais j'ai totalement échoué pour télécharger le Patch.

-1
répondu mustafa 2012-11-17 11:25:38