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

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

[code] 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 ) );

[/code]

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.

[code] 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 ) );

[/code]

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

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?

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!

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:

[code]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.(HQLQueryPlan.java:77)
at org.hibernate.engine.query.HQLQueryPlan.(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 -
\nErro nao tratado!
Local:/mercadodolivro/Pesquisa.do
\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.(HQLQueryPlan.java:77)
at org.hibernate.engine.query.HQLQueryPlan.(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)
[/code]

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

Muito Obrigado gente…

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

up

ninguém??

[quote=Luiz Henrique Coura]Estou paginando umas funcionalidades do meu sistema e uma delas está me dando trabalho.

[code] 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 ) );

[/code]
[/quote]

System.out.print(query.list().size());