Domanda

Per farla breve:l'ibernazione non supporta le proiezioni e le query per 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, l'SQL generato continua ad avere una classe where che si riferisce a just y0_= ?invece di this_.city.

Ho già provato diversi approcci e ho cercato nel tracker dei problemi ma non ho trovato nulla al riguardo.

Ho anche provato a utilizzare Projection alias 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 utilizzato proiezioni e query tramite esempi?

È stato utile?

Soluzione

Posso vedere la tua classe Utente?Si tratta solo dell'utilizzo delle restrizioni riportate di seguito.Non vedo perché Restrizioni dovrebbe essere davvero diverso da Esempi (penso però che i campi null vengano ignorati per impostazione predefinita 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 alaistToBean, ma ne ho appena letto.Potresti anche semplicemente scorrere i risultati..

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

Se necessario, puoi popolare manualmente l'utente in questo modo.

È difficile esaminare il problema senza ulteriori informazioni per diagnosticare il problema.

Altri suggerimenti

Il problema sembra verificarsi quando si dispone di un alias con lo stesso nome della proprietà Objects.Hibernate sembra prendere l'alias e usarlo nel file sql.L'ho trovato documentato Qui E Qui, e credo che si tratti di un bug di Hibernate, anche se non sono sicuro che il team di Hibernate sia d'accordo.

Ad ogni modo, ho trovato una soluzione semplice 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 modificato la mia restrizione per utilizzare "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 a un problema doloroso.Non so come questa correzione si tradurrebbe nel problema della query per esempio, ma potrebbe avvicinarti.

Il vero problema qui è che c'è un bug in hibernate in cui utilizza gli alias dell'elenco di selezione nella clausola where:

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

Nel caso in cui qualcuno arrivi qui in cerca di risposte, vai a guardare il biglietto.Ci sono voluti 5 anni per risolverlo, ma in teoria sarà in una delle prossime versioni e poi sospetto che il tuo problema scomparirà.

Sto affrontando un problema simile.Sto utilizzando Query by example e desidero ordinare i risultati in base a un campo personalizzato.In SQL farei qualcosa del tipo:

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

Funziona bene senza la clausola ordine per.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 eccezione.Soluzione alternativa con Questo non funziona neanche.

PS:poiché non sono riuscito a trovare alcuna documentazione elaborata sull'uso di QBE per Hibernate, tutto quanto sopra è principalmente un approccio per tentativi ed errori

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

Non lo penso davvero, quello che posso trovare è la parola "questa". Fa sì che l'ibernazione non includa alcuna restrizione nella sua query, il che significa che ha ottenuto tutti gli elenchi di record.Per quanto riguarda il bug di ibernazione segnalato, posso vedere che è stato segnalato come risolto ma non sono riuscito assolutamente a scaricare la patch.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top