Frage

Um es kurz zu machen:hibernate nicht unterstützt Projektionen und query by example?Ich fand diesen Beitrag:

Der code ist:

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

Wie das andere poster gesagt, Die generierte sql-hält mit einer where-Klasse bezieht sich nur y0_= ?statt this_.Stadt.

Ich habe bereits versucht, mehrere Ansätze, und suchte den issue-tracker, aber diesbezüglich nichts gefunden.

Ich habe sogar versucht zu verwenden-Projektion alias und Transformatoren, aber es funktioniert nicht:

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

Hat jemand verwendet, Projektionen und query by example ?

War es hilfreich?

Lösung

Ich kann sehen, Ihre Benutzer-Klasse?Dies ist nur mit Einschränkungen unten.Ich sehe nicht ein, warum die Einschränkungen würden wirklich anders als die Beispiele (ich denke, null-Felder bekommen, ignoriert standardmäßig in den Beispielen, wenn).

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

Ich habe noch nie verwendet die alaistToBean, aber ich habe gerade darüber gelesen.Man könnte auch einfach Loop-Schleife über die Ergebnisse..

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

Wenn Sie müssen, können Sie es manuell ausfüllen Benutzer sich auf diese Weise.

Seine Art von schwer zu schauen, das Problem ohne weitere Informationen das Problem zu diagnostizieren.

Andere Tipps

Das problem scheint zu passieren, wenn Sie einen Aliasnamen den gleichen Namen wie die Objekte, die Eigentum.Hibernate scheint zu Holen, den alias ein, und verwenden Sie es in sql.Ich fand dieses dokumentiert hier und hier, und ich glaube, dass es ein bug in Hibernate, obwohl ich nicht sicher bin, dass das Hibernate-team stimmt.

Entweder Weg, die ich gefunden habe, ein einfaches umgehen, das funktioniert in meinem Fall.Ihre Laufleistung kann variieren.Die details sind unten, ich habe versucht, den code vereinfachen, für dieses Beispiel, also ich entschuldige mich für etwaige Fehler oder Tippfehler ist:

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

Produzieren würde dieses 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 ? ) 

Was verursacht einen Fehler: java.sql.SQLException:ORA-00904:"Y1_":ungültige Bezeichner

Aber, wenn ich änderte meine Beschränkung auf "das", wie so:

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

Es produziert die folgenden sql und mein problem war gelöst.

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

Das ist es!Eine ziemlich einfache Lösung zu einem schmerzhaften problem.Ich weiß nicht, wie dies zu beheben wäre zu übersetzen, um die query by example-problem, aber es kann erhalten Sie näher.

Das eigentliche problem hier ist, dass es ein bug in hibernate, wo es mithilfe von select-Liste Aliase, die in der where-Klausel:

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

Nur für den Fall jemand landet hier auf der Suche nach Antworten, dann schauen Sie das ticket.Es dauerte 5 Jahre zu beheben, aber in der Theorie werden in einem der nächsten releases und dann ich vermute, Ihr Problem wird Weggehen.

Ich stehe vor einem ähnlichen problem.Ich bin mit der Abfrage durch Beispiel und ich möchte, um die Ergebnisse zu Sortieren, indem Sie ein benutzerdefiniertes Feld.In SQL würde ich etwas tun wie:

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

Es funktioniert gut, ohne die order by-Klausel.Was ich bekam, ist

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

Aber wenn ich hinzufügen

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

Ich bekomme eine org.Ruhezustand.QueryException:konnte nicht aufgelöst Eigenschaft:diff Ausnahme.Workaround mit diese nicht Arbeit entweder.

PS:ich konnte nicht finden, eine aufwändige Dokumentation über die Verwendung von QBE Ruhezustand, das ganze Zeug oben ist vor allem die trial-and-error-Ansatz

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

Ich glaube eigentlich nicht, dass das so ist, was ich finden kann, ist das Wort "this". bewirkt, dass der Ruhezustand nicht irgendwelche Einschränkungen in Ihrer Abfrage, was bedeutet, dass es hat alle Rekorde listet.Über die hibernate-Fehler, der gemeldet wurde, ich kann sehen, es wird berichtet, wie fest aber ich habe Total failed to download Patch.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top