Olá,
Como faço para saber quantas linhas um determinado objeto criteria irá retornar?
Olá,
Como faço para saber quantas linhas um determinado objeto criteria irá retornar?
Estou longe de um completador de códigos, não sei se existe um método que retorne isso, mas provavelmente você só terá essa informação após a Criteria ter sido realizada.
Dessa forma um:
int qtde = criteria.list().size();
deve funcionar.
Falow
O problema é que se eu fizer desse jeito terei que executar primeiramente o criteria e provavelmente serão retornados muitos dados. Não quero trazer todos os dados de uma só vez, pois iria demorar muito para o usuário. Estou tentando implementar um relatorio web com paginação. Contudo, preciso, pelo menos, dizer quantos dados a consulta do usuário irá retornar e mostrar destes dados apenas a primeira página.
http://displaytag.sourceforge.net/11/
acredito que isso resolva o seu problema
Olah Guimoz,
Essa framework funciona bem com JSF e JPA (com Hibernate)? Acho que esqueci de dizer, mas estou utilizando essas tecnologias.
Outra coisa, tem como extrair o SQL que serah gerado a partir do Criteria? Se eu conseguir obter uma string com esse SQL, possu utiliza-la como uma subquery em uma query do tipo:
"select count(*) from ("+subquerydocriteria+")"
Caso nao seja possivel, acho que vou substituir o que usei em Criteria para SQL puro. Pensei que o criteria fosse melhorar a minha vida, mas… =(
Bom, você não precisa extrair o SQL gerado pelo Criteria para fazer um SELECT COUNT().
Você pode fazer um SELECT COUNT() utilizando o proprio Criteria.
Desta forma:
Criteria criteria = sessao.getSessao().createCriteria(Cidade.class);
criteria.setProjection(Projections.rowCount());
List<Integer> resultado = (List<Integer>) criteria.list();
System.out.println(lista.get(0));
int rowCount = lista.get(0);
System.out.println(rowCount);
O segredo é o criteria.setProjection(Projections.rowCount());
Se estiver com a visualização do código SQL gerado (opção “show_sql” da configuração do Hibernate), você verá que ele gerou um “select count(*) from cidade”.
Com isso você pode incluir também todos os filtros que quiser, por exemplo as cidades que começam com “CA”:
Criteria criteria = sessao.getSessao().createCriteria(Cidade.class);
criteria.add(Expression.ilike("nome", "ca%"));
criteria.setProjection(Projections.rowCount());
List<Integer> resultado = (List<Integer>) criteria.list();
System.out.println(lista.get(0));
int rowCount = lista.get(0);
System.out.println(rowCount);
Eu também no começo não gostava muito da idéia de ter meu código SQL gerado, mas utilizando bastante o Criteria percebi como fica tudo muito mais simples, eficaz e principalmente mais semântico.
Se empenhe bastante no Criteria e verá que ele vai sim melhorar sua vida.
Abraços
Mas com esse codigo eu iria alterar o sql original e eu preciso dos dois. Depois como eu faria para voltar ao estado inicial?
Criteria criteria = sessao.getSessao().createCriteria(Cidade.class);
criteria.add(Expression.ilike("nome", "ca%"));
criteria.setProjection(Projections.rowCount());
List<Integer> lista = (List<Integer>) criteria.list();
//Pega a quantidade retornada pelo COUNT(*) - primeiro campo
int rowCount = lista.get(0);
//Imprime a qtde de registros à retornar
System.out.println(rowCount);
//Limpa o projections
criteria.setProjection(null);
//Realiza novamente a query, sem o COUNT(*)
List<Cidade> listaCidade = (List<Cidade>) criteria.list();
//Percorre os registros encontrados imprimindo o nome da cidade
for (Cidade cidade : listaCidade) {
System.out.println(cidade.getNome());
}
Olá raci0nal,
Obrigado pela dica, consegui pegar o número de registros, mas quando seto a propriedade projection para null obtenho uma exceção:
ORA-00936: expressão não encontrada
Se eu isolar o código deixando apenas aquele que seta a propriedade para null obtenho outra exceção:
The “.” operator was supplied with an index value of type “java.lang.String” to be applied to a List or array, but that value cannot be converted to an integer.
davimcabral,
O primeiro erro é de SQL, então verifique qual foi o código SQL que o Hibernate gerou, talvez possamos identificar onde está o erro.
Se possível cole aqui o seu código Java para eu dar uma olhada.
Olá raci0nal,
Aparentemente ele está devolvendo o SQL corretamente.
O select do count(*) fica assim
select
count(*) as y0_
from
juradmin.TB_JURISPRUDENCIA this_
inner join
apadmin.vw_juiz aprolator1_
on this_.cd_prolator=aprolator1_.cd_juiz
inner join
apadmin.vw_juiz arelator2_
on this_.cd_relator=arelator2_.cd_juiz
where
(
this_.cd_prolator=?
or this_.cd_relator=?
)
and lower(this_.ds_ementa) like ?
e o select que retorna os objetos fica assim
select
this_.nu_jurisp as nu1_1_5_,
this_.dt_julgamento as dt2_1_5_,
this_.dt_publicacao as dt3_1_5_,
this_.lb_decisao as lb4_1_5_,
this_.ds_ementa as ds5_1_5_,
this_.nu_acordao as nu6_1_5_,
this_.cd_prolator as cd7_1_5_,
this_.cd_relator as cd8_1_5_,
processo4_.nu_jurisp as nu1_2_0_,
processo4_.nu_ano as nu3_2_0_,
processo4_.cd_classe as cd7_2_0_,
processo4_.nu_vara as nu4_2_0_,
processo4_.nu_processo as nu5_2_0_,
processo4_.sq_processo as sq6_2_0_,
(select
n.nu_digito
from
apadmin.tb_proc_seq n
where
n.nu_processo = processo4_.nu_processo
and n.nu_ano = processo4_.nu_ano
and n.nu_vara = processo4_.nu_vara
and n.sq_processo = processo4_.sq_processo) as formula0_0_,
classe5_.cd_classe as cd1_4_1_,
classe5_.nm_classe as nm2_4_1_,
classe5_.ds_classe as ds3_4_1_,
vara6_.nu_vara as nu1_3_2_,
vara6_.nm_vara as nm2_3_2_,
aprolator1_.cd_juiz as cd1_5_3_,
aprolator1_.nm_juiz as nm2_5_3_,
arelator2_.cd_juiz as cd1_5_4_,
arelator2_.nm_juiz as nm2_5_4_
from
juradmin.TB_JURISPRUDENCIA this_
left outer join
juradmin.tb_jurisprudencia processo4_
on this_.nu_jurisp=processo4_.nu_jurisp
left outer join
apadmin.TB_CLASSE classe5_
on processo4_.cd_classe=classe5_.cd_classe
left outer join
apadmin.tb_vara vara6_
on processo4_.nu_vara=vara6_.nu_vara
inner join
apadmin.vw_juiz aprolator1_
on this_.cd_prolator=aprolator1_.cd_juiz
inner join
apadmin.vw_juiz arelator2_
on this_.cd_relator=arelator2_.cd_juiz
where
(
this_.cd_prolator=?
or this_.cd_relator=?
)
and lower(this_.ds_ementa) like ?
A exceção que recebo é a seguinte :
org.apache.jasper.JasperException: javax.faces.el.ReferenceSyntaxException: The "." operator was supplied with an index value of type "java.lang.String" to be applied to a List or array, but that value cannot be converted to an integer.
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:476)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:389)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:346)
com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:152)
org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:108)
org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:216)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:107)
com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:245)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:137)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:214)
org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:307)
org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141)
org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281)
root cause
javax.faces.el.EvaluationException: javax.faces.el.ReferenceSyntaxException: The "." operator was supplied with an index value of type "java.lang.String" to be applied to a List or array, but that value cannot be converted to an integer.
com.sun.faces.el.ValueBindingImpl.getValue(ValueBindingImpl.java:190)
com.sun.faces.el.ValueBindingImpl.getValue(ValueBindingImpl.java:143)
javax.faces.component.UIOutput.getValue(UIOutput.java:167)
com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:102)
com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:221)
com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:199)
javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:740)
com.sun.faces.renderkit.html_basic.CommandLinkRenderer.encodeChildren(CommandLinkRenderer.java:295)
javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:721)
com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:465)
com.sun.faces.renderkit.html_basic.GridRenderer.encodeChildren(GridRenderer.java:253)
javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:721)
org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:282)
org.ajax4jsf.renderkit.RendererBase.renderChildren(RendererBase.java:262)
org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:284)
org.richfaces.renderkit.AbstractRowsRenderer.encodeCellChildren(AbstractRowsRenderer.java:283)
org.richfaces.renderkit.html.ColgroupRenderer.encodeChildren(ColgroupRenderer.java:98)
javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:721)
org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:282)
org.richfaces.renderkit.AbstractRowsRenderer.encodeCellChildren(AbstractRowsRenderer.java:283)
org.richfaces.renderkit.AbstractTableRenderer.encodeOneRow(AbstractTableRenderer.java:216)
org.richfaces.renderkit.AbstractRowsRenderer.process(AbstractRowsRenderer.java:87)
org.ajax4jsf.model.SequenceDataModel.walk(SequenceDataModel.java:101)
org.ajax4jsf.component.UIDataAdaptor.walk(UIDataAdaptor.java:968)
org.richfaces.renderkit.AbstractRowsRenderer.encodeRows(AbstractRowsRenderer.java:104)
org.richfaces.renderkit.AbstractRowsRenderer.encodeChildren(AbstractRowsRenderer.java:136)
javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:721)
javax.faces.webapp.UIComponentTag.encodeChildren(UIComponentTag.java:629)
javax.faces.webapp.UIComponentTag.doEndTag(UIComponentTag.java:566)
org.apache.jsp.listar_jsp._jspx_meth_rich_005fdataTable_005f0(listar_jsp.java:242)
org.apache.jsp.listar_jsp._jspx_meth_h_005fform_005f0(listar_jsp.java:193)
org.apache.jsp.listar_jsp._jspx_meth_f_005fview_005f0(listar_jsp.java:157)
org.apache.jsp.listar_jsp._jspService(listar_jsp.java:114)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:346)
com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:152)
org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:108)
org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:216)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:107)
com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:245)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:137)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:214)
org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:307)
org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141)
org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281)
root cause
javax.faces.el.ReferenceSyntaxException: The "." operator was supplied with an index value of type "java.lang.String" to be applied to a List or array, but that value cannot be converted to an integer.
com.sun.faces.el.impl.ArraySuffix.evaluate(ArraySuffix.java:183)
com.sun.faces.el.impl.ComplexValue.evaluate(ComplexValue.java:171)
com.sun.faces.el.impl.ExpressionEvaluatorImpl.evaluate(ExpressionEvaluatorImpl.java:263)
com.sun.faces.el.ValueBindingImpl.getValue(ValueBindingImpl.java:160)
com.sun.faces.el.ValueBindingImpl.getValue(ValueBindingImpl.java:143)
javax.faces.component.UIOutput.getValue(UIOutput.java:167)
com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:102)
com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:221)
com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:199)
javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:740)
com.sun.faces.renderkit.html_basic.CommandLinkRenderer.encodeChildren(CommandLinkRenderer.java:295)
javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:721)
com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:465)
com.sun.faces.renderkit.html_basic.GridRenderer.encodeChildren(GridRenderer.java:253)
javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:721)
org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:282)
org.ajax4jsf.renderkit.RendererBase.renderChildren(RendererBase.java:262)
org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:284)
org.richfaces.renderkit.AbstractRowsRenderer.encodeCellChildren(AbstractRowsRenderer.java:283)
org.richfaces.renderkit.html.ColgroupRenderer.encodeChildren(ColgroupRenderer.java:98)
javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:721)
org.ajax4jsf.renderkit.RendererBase.renderChild(RendererBase.java:282)
org.richfaces.renderkit.AbstractRowsRenderer.encodeCellChildren(AbstractRowsRenderer.java:283)
org.richfaces.renderkit.AbstractTableRenderer.encodeOneRow(AbstractTableRenderer.java:216)
org.richfaces.renderkit.AbstractRowsRenderer.process(AbstractRowsRenderer.java:87)
org.ajax4jsf.model.SequenceDataModel.walk(SequenceDataModel.java:101)
org.ajax4jsf.component.UIDataAdaptor.walk(UIDataAdaptor.java:968)
org.richfaces.renderkit.AbstractRowsRenderer.encodeRows(AbstractRowsRenderer.java:104)
org.richfaces.renderkit.AbstractRowsRenderer.encodeChildren(AbstractRowsRenderer.java:136)
javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:721)
javax.faces.webapp.UIComponentTag.encodeChildren(UIComponentTag.java:629)
javax.faces.webapp.UIComponentTag.doEndTag(UIComponentTag.java:566)
org.apache.jsp.listar_jsp._jspx_meth_rich_005fdataTable_005f0(listar_jsp.java:242)
org.apache.jsp.listar_jsp._jspx_meth_h_005fform_005f0(listar_jsp.java:193)
org.apache.jsp.listar_jsp._jspx_meth_f_005fview_005f0(listar_jsp.java:157)
org.apache.jsp.listar_jsp._jspService(listar_jsp.java:114)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:346)
com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:152)
org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:108)
org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:216)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:107)
com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:245)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:137)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:214)
org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:307)
org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141)
org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281)
Só como informação, quando tiro os comandos que setam a propriedade projection para null tudo funciona corretamente. Se eu quiser saber o número de registros eu consigo, se eu quiser receber a lista com os objetos eu também consigo, porém se eu quiser as duas coisas obtenho o erro acima.
Nessa caso amigo, separe os procedimentos em Criterias diferentes.
Crie um para o RowCount e um para a Consulta.
Vai resolver o problema, sem que nos matemos muito para descobrir qual é.
Falow… abraço
olá raci0nal,
fiz isso mesmo, dupliquei as linhas de código só para criar uma forma de saber quantos registros meu filtro irá retornar. =/ ficou seboso, mas foi o jeito. valeu pela força, vc me ajudou bastante.
Às ordens!
Foi bom que deu para ver o nível de “inteligencia” do Hibernate, note a diferença entre o número de tabelas que ele envolve para trazer os objetos, e para fazer o COUNT(*).
Talvez um programador não faria isso, aliás usaria sua primeira opção que seria um SELECT com SUB-SELECT, o que notavelmente ficaria muito mais “pesado” do que a solução do Hibernate.
Abraços
kkk verdade =)
up