java - query - proyecciones hibernate
Hibernate Query por ejemplo y proyecciones (6)
Para abreviar: hibernate no admite proyecciones y consulta por ejemplo? Encontré esta publicación:
El código es este:
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))
Al igual que el otro cartel, dijo: El sql generado sigue teniendo una clase en donde solo se refiere a y0_ =? en lugar de this_.city
Ya probé varios enfoques y busqué el rastreador de problemas, pero no encontré nada sobre esto.
Incluso traté de usar alias de proyección y transformadores, pero no funciona:
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));
¿Alguien ha usado proyecciones y consultas por ejemplo?
¿Puedo ver tu clase de Usuario? Esto es solo usando restricciones a continuación. No veo por qué las Restricciones serían realmente diferentes a los Ejemplos (creo que los campos nulos son ignorados por defecto en los ejemplos).
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();
Nunca he usado alaistToBean, pero acabo de leer al respecto. También podría simplemente recorrer los resultados.
List<Object> rows = criteria.list();
for(Object r: rows){
Object[] row = (Object[]) r;
Type t = ((<Type>) row[0]);
}
Si es necesario, puede llenar manualmente el usuario usted mismo de esa manera.
Es difícil ver el problema sin más información para diagnosticar el problema.
Estoy enfrentando un problema similar. Estoy usando Consulta por ejemplo y quiero ordenar los resultados por un campo personalizado. En SQL, haría algo como:
select pageNo, abs(pageNo - 434) as diff
from relA
where year = 2009
order by diff
Funciona bien sin la orden por cláusula. Lo que obtuve es
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);
Pero cuando agrego
crit.addOrder(Order.asc("diff"));
Obtengo una org.hibernate.QueryException: no pude resolver la propiedad: diff excepción. La solución con esto tampoco funciona.
PD: como no pude encontrar ninguna documentación elaborada sobre el uso de QBE para Hibernate, todo lo anterior es principalmente un enfoque de prueba y error
El verdadero problema aquí es que hay un error en hibernación donde usa alias de lista de selección en la cláusula-donde:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-817
En caso de que alguien aterrice aquí buscando respuestas, ve a ver el boleto. Me tomó 5 años arreglarlo, pero en teoría estará en uno de los próximos lanzamientos y entonces sospecho que su problema desaparecerá.
El problema parece ocurrir cuando tienes un alias del mismo nombre que la propiedad de los objetos. Hibernate parece recoger el alias y usarlo en sql. Encontré esto documentado aquí y aquí , y creo que es un error en Hibernate, aunque no estoy seguro de que el equipo de Hibernate esté de acuerdo.
De cualquier manera, he encontrado un trabajo simple que funciona en mi caso. Su experiencia puede ser diferente. Los detalles están a continuación, traté de simplificar el código de esta muestra, así que me disculpo por cualquier error o error tipográfico:
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));
Produciría este 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 ? )
Lo que provocaba un error: java.sql.SQLException: ORA-00904: "Y1_": identificador no válido
Pero, cuando cambié mi restricción para usar "esto", así:
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));
Produjo el siguiente sql y mi problema fue resuelto.
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 ? )
¡Eso es! Una solución bastante simple para un problema doloroso. No sé cómo esta solución se traduciría en un problema de consulta por ejemplo, pero puede acercarlo más.
Realmente no lo creo, lo que puedo encontrar es la palabra "esto". hace que hibernate no incluya ninguna restricción en su consulta, lo que significa que obtuvo todas las listas de registros. Sobre el error de hibernación que se informó, puedo ver que se informó como corregido, pero no pude descargar el parche.
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);