Per farla breve: Hibernate non supporta le proiezioni e la query con l'esempio? Ho trovato questo post:
Il codice è questo:
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))
Come ha detto l'altro poster, lo sql generato continua ad avere una classe in cui si fa riferimento solo a y0_ =? invece di this_.city .
Ho già provato diversi approcci e ho cercato il tracker dei problemi ma non ho trovato nulla a riguardo.
Ho persino provato ad usare alias di Projection e Transformers, ma non funziona:
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));
Qualcuno ha usato proiezioni e query con l'esempio?
Posso vedere la tua classe utente? Questo è solo usando le restrizioni di seguito. Non vedo perché le restrizioni sarebbero davvero diverse dagli esempi (penso che i campi nulli vengano ignorati di default negli esempi).
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();
Non ho mai usato l'alaistToBean, ma ho appena letto su di esso. Potresti anche ripetere i risultati ..
List<Object> rows = criteria.list();
for(Object r: rows){
Object[] row = (Object[]) r;
Type t = ((<Type>) row[0]);
}
Se necessario, puoi compilare manualmente l'utente in questo modo.
È un po 'difficile da esaminare nel problema senza ulteriori informazioni per diagnosticare il problema.
Il problema sembra verificarsi quando si ha un alias con lo stesso nome della proprietà objects. Hibernate sembra raccogliere l'alias e usarlo nella sql. Ho trovato questo documento qui e qui , e credo che sia un bug in Hibernate, anche se non sono sicuro che il team di Hibernate sia d'accordo.
Ad ogni modo, ho trovato un semplice lavoro che funziona nel mio caso. Il tuo chilometraggio può variare. I dettagli sono di seguito, ho provato a semplificare il codice per questo esempio, quindi mi scuso per eventuali errori o errori di battitura:
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));
Produrrebbe questo 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 ? )
Che stava causando un errore: Java.sql.SQLException: ORA-00904: "Y1_": identificatore non valido
Ma, quando ho cambiato la mia restrizione per usare "questo", in questo modo:
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));
Ha prodotto il seguente sql e il mio problema è stato risolto.
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 ? )
Questo è tutto! Una soluzione piuttosto semplice per un problema doloroso. Non so come questa correzione possa tradursi nella query con il problema di esempio, ma potrebbe avvicinarti.
Il vero problema qui è che c'è un bug in ibernazione dove usa gli alias select-list nella clausola where:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-817
Nel caso in cui qualcuno atterra qui in cerca di risposte, vai a dare un'occhiata al biglietto. Ci sono voluti 5 anni per risolvere il problema ma in teoria sarà in una delle prossime versioni e quindi sospetto che il tuo problema andrà via.
Sto affrontando un problema simile. Sto usando Query per esempio e voglio ordinare i risultati per un campo personalizzato. In SQL vorrei fare qualcosa di simile:
select pageNo, abs(pageNo - 434) as diff
from relA
where year = 2009
order by diff
Funziona bene senza la clausola order-by-clausola. Quello che ho ottenuto è
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);
Ma quando aggiungo
crit.addOrder(Order.asc("diff"));
Ottengo un org.hibernate.QueryException: impossibile risolvere la proprietà: diff exception. Anche la soluzione con this non funziona.
PS: dato che non sono riuscito a trovare alcuna documentazione elaborata sull'uso di QBE per Hibernate, tutto il materiale sopra riportato è principalmente un approccio trial-and-error
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);