Dúvida com Criteria, Projections.projectionList(), Projections.rowCount()

7 respostas
L

Estou paginando umas funcionalidades do meu sistema e uma delas está me dando trabalho.

Criteria query = HibernateSessionProvider.getSession().createCriteria( PackageFilter.class );
        
        query.setProjection( Projections.projectionList()
                             .add( Projections.groupProperty( "source.ip.ip" ) ) 
                             .add( Projections.property( "source.port.port" ) ) 
                             .add( Projections.groupProperty( "action" ) ) 
                             .add( Projections.groupProperty( "target.ip.ip" ) ) 
                             .add( Projections.groupProperty( "target.port.port" ) )
                             .add( Projections.property( "protocol" ) )
                             .add( Projections.count( "source.ip.ip" ) ) );
        
        query.add( Restrictions.eq( "server.idServer", idServer ) );
        
        Criterion sourceCriterion = Restrictions.like( "source.ip.ip", host, MatchMode.END );
        Criterion targetCriterion = Restrictions.like( "target.ip.ip", host, MatchMode.END );
        query.add( Restrictions.or( sourceCriterion, targetCriterion ) );
        query.add( Restrictions.between( "date", initialDate, finalDate ) );

Essa é minha query e gostaria de fazer uma projeção de qts linhas são produzidas por ela.

Query gerada (rs formatado!):
select 
  this_.source as y0_, 
  this_.sourcePort as y1_, 
  this_.action as y2_, 
  this_.target as y3_, 
  this_.targetPort as y4_, 
  this_.protocol as y5_, 
  count(this_.source) as y6_ 
from 
  PackageFilter this_ 
where 
  this_.idServer=? 
and 
  (this_.source like ? or this_.target like ?) 
and 
  this_.date between ? and ? 
group by 
  this_.source, 
  this_.action, 
  this_.target, 
  this_.targetPort

Se eu inserir Projections.rowCount( ) o resultado retornado não é o número de linhas, mas sim o total do agrupamento criado.

Criteria query = HibernateSessionProvider.getSession().createCriteria( PackageFilter.class );
        
        query.setProjection( Projections.projectionList()
                             .add( Projections.rowCount( ) 
                             .add( Projections.groupProperty( "source.ip.ip" ) ) 
                             .add( Projections.property( "source.port.port" ) ) 
                             .add( Projections.groupProperty( "action" ) ) 
                             .add( Projections.groupProperty( "target.ip.ip" ) ) 
                             .add( Projections.groupProperty( "target.port.port" ) )
                             .add( Projections.property( "protocol" ) )
                             .add( Projections.count( "source.ip.ip" ) ) );
        
        query.add( Restrictions.eq( "server.idServer", idServer ) );
        
        Criterion sourceCriterion = Restrictions.like( "source.ip.ip", host, MatchMode.END );
        Criterion targetCriterion = Restrictions.like( "target.ip.ip", host, MatchMode.END );
        query.add( Restrictions.or( sourceCriterion, targetCriterion ) );
        query.add( Restrictions.between( "date", initialDate, finalDate ) );

O q eu faço para retornar a qtd de linhas geradas?

7 Respostas

L

Mas é claro, subquery:

select count(*) from (SELECT)

Isso me retornará o número de linhas executadas em minha query.

Mas como eu faço isso utilizando Criteria?

L

Bom galera, consegui resolver, porém a única maneira de resolver isso foi executando SQL nativa.

O Hibernate não permite SQL em clausula FROM, então depois de várias pesquisas decidi usar SQL nativa mesmo.

vlw!

C

Vamos reviver este tópico... hehehe

Estou com o mesmo problema, executo o sql abaixo no Postgresql e ocorre tudo bem.

select count(*) from (select titulo from livro group by titulo) as t

Se eu criar o sql acima como hql no hibernate ele da erro.

O sql que eu crio como hql é o seguinte: select count(*) from (select l.titulo, count(*) as soma from Livro as l inner join l.livraria as lv where lv.ativo = true and l.titulo like '%COM%' group by l.titulo order by l.titulo asc ) as tab

Segue erro abaixo:

07/11/2007 08:25:45 org.hibernate.hql.ast.ErrorCounter reportError
SEVERE: line 1:22: unexpected token: (
07/11/2007 08:25:45 org.hibernate.hql.ast.ErrorCounter reportError
SEVERE: line 1:40: unexpected token: count
07/11/2007 08:25:47 org.apache.struts.action.RequestProcessor processException
WARNING: Unhandled Exception thrown: class org.hibernate.hql.ast.QuerySyntaxException
07/11/2007 08:25:47 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet action threw exception
org.hibernate.hql.ast.QuerySyntaxException: unexpected token: ( near line 1, column 22 [select count(*) from (select l.titulo, count(*) as soma from br.ml.objeto.Livro as l inner join l.livraria as lv  where lv.ativo = true  and l.titulo like '%COM%'  group by l.titulo order by l.titulo asc ) as tab]
	at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:31)
	at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:24)
	at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:59)
	at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:258)
	at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:157)
	at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:111)
	at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
	at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:56)
	at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72)
	at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
	at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
	at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1623)
	at br.ml.dao.entity.LivroDao.pesquisaSimples(LivroDao.java:170)
	at br.ml.action.PesquisaAction.execute(PesquisaAction.java:66)

08:25:47,312 FATAL ErroAction:72 - <br>\nErro nao tratado!<br>Local:/mercadodolivro/Pesquisa.do<br>\n
org.hibernate.hql.ast.QuerySyntaxException: unexpected token: ( near line 1, column 22 [select count(*) from (select l.titulo, count(*) as soma from br.ml.objeto.Livro as l inner join l.livraria as lv  where lv.ativo = true  and l.titulo like '%COM%'  group by l.titulo order by l.titulo asc ) as tab]
	at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:31)
	at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:24)
	at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:59)
	at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:258)
	at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:157)
	at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:111)
	at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
	at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:56)
	at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:72)
	at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
	at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
	at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1623)

Fora usar sql nativa, existe alguma forma do hibernate reconhecer tal sql ?

Muito Obrigado gente..

D

Estou com o mesmo problema, só que quero continuar usando o criteria. Alguém descobriu como resolver?

C

up

K

ninguém??

J
Luiz Henrique Coura:
Estou paginando umas funcionalidades do meu sistema e uma delas está me dando trabalho.
Criteria query = HibernateSessionProvider.getSession().createCriteria( PackageFilter.class );
        
        query.setProjection( Projections.projectionList()
                             .add( Projections.groupProperty( "source.ip.ip" ) ) 
                             .add( Projections.property( "source.port.port" ) ) 
                             .add( Projections.groupProperty( "action" ) ) 
                             .add( Projections.groupProperty( "target.ip.ip" ) ) 
                             .add( Projections.groupProperty( "target.port.port" ) )
                             .add( Projections.property( "protocol" ) )
                             .add( Projections.count( "source.ip.ip" ) ) );
        
        query.add( Restrictions.eq( "server.idServer", idServer ) );
        
        Criterion sourceCriterion = Restrictions.like( "source.ip.ip", host, MatchMode.END );
        Criterion targetCriterion = Restrictions.like( "target.ip.ip", host, MatchMode.END );
        query.add( Restrictions.or( sourceCriterion, targetCriterion ) );
        query.add( Restrictions.between( "date", initialDate, finalDate ) );
System.out.print(query.list().size());
Criado 22 de março de 2007
Ultima resposta 7 de ago. de 2013
Respostas 7
Participantes 6