Question

En résumé: hibernate ne prend pas en charge 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 affiche, sql généré continue d’avoir une classe where se référant à y0_ =? au lieu de this_.city .

J'ai déjà essayé plusieurs approches et cherché dans l'outil de suivi des problèmes, mais rien trouvé à ce sujet.

J'ai même essayé d'utiliser l'alias de projection et les transformateurs, mais cela 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 at-il utilisé des projections et des requêtes par exemple?

Était-ce utile?

La solution

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

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é alaistToBean, mais je viens de lire à ce sujet. Vous pouvez également simplement parcourir les résultats.

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

Si vous devez le faire, vous pouvez renseigner manuellement l'utilisateur vous-même de cette façon.

Il est difficile d'examiner le problème sans disposer de plus d'informations pour le diagnostiquer.

Autres conseils

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é cette documentation ici et ici , et moi crois que c’est un bug d’Hibernate, même si je ne suis pas sûr que l’équipe d’Hibernate soit d’accord.

De toute façon, j’ai trouvé un moyen simple de contourner le problème. Votre kilométrage peut varier. Les détails sont ci-dessous, j'ai essayé de simplifier le code pour cet exemple, donc je m'excuse pour les erreurs ou les 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));

Produirait 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 provoqué une erreur: java.sql.SQLException: ORA-00904: "Y1_": identificateur non valide

Mais, lorsque j'ai modifié ma restriction, elle a été utilisée de la manière suivante:

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));

Cela a produit le code SQL suivant 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 ça! Une solution assez simple à un problème douloureux. Je ne sais pas comment ce correctif résoudrait le problème requête par exemple, mais cela pourrait vous rapprocher.

Le vrai problème ici est qu'il existe un bogue dans hibernate qui utilise des alias de liste de sélection dans la clause where:

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

Juste au cas où quelqu'un atterrirait ici à la recherche de réponses, allez voir le billet. Cela a pris 5 ans pour résoudre le problème, mais en théorie ce sera dans l’une des prochaines versions et ensuite, je suppose que votre problème disparaîtra.

Je suis confronté à un problème similaire. J'utilise une requête par exemple et je souhaite trier les résultats selon un champ personnalisé. En SQL, je ferais quelque chose comme:

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

Cela fonctionne très bien sans ordre par clause. Ce que j'ai obtenu 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 reçois une exception org.hibernate.QueryException: impossible de résoudre la propriété: diff . La solution de contournement avec this ne fonctionne pas non plus.

PS: je n’ai trouvé aucune documentation détaillée sur l’utilisation de QBE pour Hibernate, tout ce qui est décrit ci-dessus est principalement une approche empirique

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);

Je ne le pense pas vraiment. Ce que je peux trouver, c’est le mot "ceci". veille à ce que l'hibernation n'inclue aucune restriction dans sa requête, ce qui signifie qu'il a toutes les listes d'enregistrements. À propos du bogue de veille prolongée qui a été signalé, je peux voir qu’il a été corrigé mais j’ai totalement échoué dans le téléchargement du correctif.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top