Problemas com passagem de parâmetro e dataTable do Primefaces

1,587 views
Skip to first unread message

Diogo Dias

unread,
Jun 16, 2011, 4:36:28 PM6/16/11
to jav...@googlegroups.com
Boa tarde, galera! 

Seguinte, estou desenvolvendo minha primeira aplicação com JSF e estou usando Primefaces,
e emperrei em 2 problemas e gostaria de pedir a ajuda de vocês :

1) Eu tenho uma tela que tem 2 panels, um de busca com um edit e um botão
   e logo abaixo outro com um datatable. Os 2 estão dentro do mesmo form. 
  Quando se clica no botão de busca, ele efetua a busca e popula o datatable com o resultado e funciona legal.
  Mas o problema e que se a lista for muito grande, o datatable não mostra tudo. 
Ex: em uma lista com o tamanho de 200 registros encontrados, o datatable mostra somente os 15 primeiros e quando eu clico no próximo do 
paginator ele não mostra nada. 

O código do datatable:

 <p:dataTable id="tableBusca" var="cliente" 
                                 value="#{buscaBean.clientesEncontrados}"
                                 emptyMessage="Nenhum cliente encontrado." rows="15"
                                 paginator="true">

O código do botão de busca:

<p:commandButton value="Buscar" 
                 image="ui-icon ui-icon-search"
                 action="#{buscaBean.buscarClientePorNome}"
                 update="tableBusca"/>

a método do bean que está associado ao botão de busca:

public String buscarClientePorNome() {
        if (!StringsUtil.isVazia(this.conteudoBusca)) {
            List<Cliente> listaEncontrados = this.clienteService.buscarClientePorNome(this.conteudoBusca);
            DataModel<Cliente> listaDataModel = new ListDataModel(listaEncontrados);

            this.setClientesEncontrados(listaDataModel);
        }

        return null;
    }

2) O segundo problema é que quando eu clico em um botão que está em uma coluna do datatable, que
   tem a função de chamar outra página e passar o cliente selecionado da tabela para uma propriedade de outro MB, o dashboardBean.
  Mas nada acontece. A action do botão está associado ao seguinte método do MB buscaBean:

public String selecionarCliente() {
        System.out.println("selecionado cliente");
        return "dashboard.xhtml";
}

O código do botão que está na coluna:

<p:column style="width: 10px">  
   <h:form>
      <p:commandButton image="ui-icon ui-icon-search" title="Selecionar cliente"
                        action="#{buscaBean.selecionarCliente}">
           <f:setPropertyActionListener value="#{cliente}"
                        target="#{dashBoardBean.clienteSelecionado}"/>
      </p:commandButton>
   </h:form>
</p:column>

Nem o println do método funciona. 

Qualquer ajuda é sempre bem vinda.

Obrigado pessoal, 

Att,
Diogo Dias








Matruskan

unread,
Jun 16, 2011, 9:56:50 PM6/16/11
to jav...@googlegroups.com
Boa noite, Diogo,


1) Você já tentou trocar o escopo do seu Bean para sessão ou aplicação para verificar se a paginação volta a funcionar?
Se você estiver usando um Bean de Request, provavelmente o modelo com os clientes é apagado após a requisição dos 15 primeiros.
Se for esse o problema, você já tem uma dica do que está acontecendo.
Se você não conseguir resolver, pode tentar isso: http://www.primefaces.org/showcase/ui/datatableScrolling.jsf
ou voltar aqui para compartilhar com a gente o que descobriu e pedir mais ajuda.


2) Se você estiver usando JSF2, você pode tentar isso:

public String selecionarCliente(Cliente c) {
        System.out.println("selecionado cliente");
        // fazer o que precisa com o cliente
        return "dashboard.xhtml";
}

<p:column style="width: 10px">  
   <h:form>
      <p:commandButton image="ui-icon ui-icon-search" title="Selecionar cliente"
                        action="#{buscaBean.selecionarCliente(cliente)}">
      </p:commandButton>
   </h:form>
</p:column>




Espero que tenha ajudado



2011/6/16 Diogo Dias <diogo....@gmail.com>







--
Você recebeu esta mensagem por que é membro do Javasf
http://groups.google.com/group/javasf
 
Conheça também o Java Brazil: http://groups.google.com/group/thejavabrazil

Diogo Dias

unread,
Jun 17, 2011, 10:33:47 AM6/17/11
to jav...@googlegroups.com
Bom dia, Matruskan! Obrigado pela ajuda!

Seguinte, coloquei o escopo do bean para Session e Application, mas não funcionou. Com ambos, é lançada uma exceção
do Hibernate, session expired! Eu uso o pattern Open session in view para iniciar uma transação e fechar, 
eu acho que é isso que está acarretando esse erro. Mas eu fiz um teste com o bean em escopo de request
eu coloquei o valor do datatable apontando para um método que retorna uma lista com 100 registros e a paginação funciona legal. 

Coloquei o datatable para escrolar, como você sugeriu, mas não funcionou. Nem no chrome nem no firefox. Não aparece a barra de rolagem
e a tabela encurta o tamanho.

Na segunda sugestão que você deu, pra mim não vai funcionar, pois estou utilizando o Tomcat 6 e a lib do EL é limitada e não aceita
passagem de parametros pelo método. Mas nem eu colocando o nome da página direto na action do botão ele funciona, ele recarrega a mesma página.

Mas eu vou continuar tentando aqui.. Valeu!
Qualquer outra sugestão é bem vinda.

Matruskan

unread,
Jun 17, 2011, 2:05:39 PM6/17/11
to jav...@googlegroups.com
Olá novamente, Diogo,

Quanto ao primeiro caso, não sei mais como resolver, vou pensar mais um pouco. No segundo caso, verifique se não há 2 forms em volta do botão (um fora da tabela e outro na coluna, por exemplo). Geralmente os botões não funcionam direito se isso acontecer.


Boa sorte!

2011/6/17 Diogo Dias <diogo....@gmail.com>

Marcelo Preis Ferreira

unread,
Jun 17, 2011, 2:50:21 PM6/17/11
to jav...@googlegroups.com
Que escopo estas trabalhando,
se for view ou session vale o que eu vou te dizer, caso contrário vai ter que fazer paginação sob demanda.

- Parecer a respeito do problemas em sim parece estar com Bean, quando você vai fazer a paginação... tem outro objeto dentro dele
o objeto tenta ler o objeto filho, como a sessão de banco de dados já foi fechada, ele da erro.

Verifique se isso se constata, Propriedade definida como LAZY, mude para EAGER nesse objeto.

Esse manager tem a lista com 200 objetos mesmo?
O Matruskan falou é verdade você sempre tem que ter um form para que botões sofram eventos,
porém eles não podem estar aninhados.

não sei se entendi direto seu problema, poste os erros que esta dando que é mais fácil
o stacktrace




Diogo Dias

unread,
Jun 17, 2011, 2:20:22 PM6/17/11
to jav...@googlegroups.com
Tinha um form, dentro desse form um datatable e dentro da coluna do datatable outro form. Terei o form de dentro da
coluna e mesmo assim não funcionou. O codigo do botão é esse:

<p:column style="width: 10px">                              
     <p:commandButton image="ui-icon ui-icon-search" title="Selecionar cliente"
           action="dashboard.xhtml" ajax="false">
           <f:setPropertyActionListener value="#{cliente}" target="#{dashBoardBean.clienteSelecionado}"/>
     </p:commandButton>                            
</p:column>

Aparentemente está tudo certo né? Não sei porque não está funcionando.

Marcelo Preis Ferreira

unread,
Jun 17, 2011, 3:54:08 PM6/17/11
to jav...@googlegroups.com
Tem certeza do que estas falando a coisa certa... com o que você deseja.

Eu uso, passar parametro assim.
<f:param name="idCliente" value="#{managed.cliente.id}" />

E no p:commandButton você define a action="#{dashBoardBean.clienteSelecionado}"

Tenta essa primeiro, ai não precisa nem paramentro.
E no p:commandButton voce define a propriedade action="#{dashBoardBean.clienteSelecionado(cliente)}"


Outro esse seu cliente acho que isso esta errado. como ele vai setar essa variável?
se não tem o managerBean.

Em action eu nunco defino navegação .xhtml, somente manager. mas não sei quem sabe seu jeito de programar seja mais interessante do que  meu.

Posta ai quando der certo!

Diogo Dias

unread,
Jun 17, 2011, 4:31:47 PM6/17/11
to jav...@googlegroups.com
Fala Marcelo,

coloquei o escopo do bean como ViewScoped e ele deu o mesmo erro quando eu coloquei
como SessionScoped e ApplicationScoped.

javax.faces.FacesException: #{buscaBean.buscarClientePorNome}: org.hibernate.SessionException: Session is closed!

Esse erro acontece quando eu clico no botão, ele nem popula a tabela.

O size da lista é 200 mesmo, e ele mostra certinho, mas quando a lista é populada pelo método de busca, a paginação não funciona, só
a primeira página.

segue o fonte da página de busca. Troquei de server, estou usando o glassfish que tem a lib da EL mais atual.

<h:body>
        <div id="container" class="ui-widget">
            <div id="header" class="ui-widget-header">
                <div>                   
                </div>
            </div>

            <div id="content">
                <h:form>
                    <div id="divCentralBusca">
                        <p:ajaxStatus style="width:16px;height:16px;">
                            <f:facet name="start">
                                <h:graphicImage library="images" name="ajaxloading.gif" />
                            </f:facet>

                            <f:facet name="complete">
                                <h:outputText value="" />
                            </f:facet>
                        </p:ajaxStatus>

                        <p:panel id="pnlBuscaCliente" header="Busca de cliente">                   
                            <h:panelGrid columns="3">
                                <h:outputText value="Digite um nome:" />
                                <p:inputText size="115" value="#{buscaBean.conteudoBusca}" />

                                <p:commandButton value="Buscar"
                                                 image="ui-icon ui-icon-search"
                                                 action="#{buscaBean.buscarClientePorNome}"
                                                 update="tableBusca"/>
                            </h:panelGrid>                   
                        </p:panel>
                    </div>

                    <div id="divCentralTabela">

                        <p:dataTable id="tableBusca" var="cliente"
                                     value="#{buscaBean.clientesEncontrados}"
                                     emptyMessage="Nenhum cliente encontrado." rows="15"
                                     paginator="true">
                            <p:column>
                                <f:facet name="header">
                                    <h:outputText value="Código" />
                                </f:facet>
                                <h:outputText value="#{cliente.codigo}" />
                            </p:column>

                            <p:column>
                                <f:facet name="header">
                                    <h:outputText value="Nome fantasia" />
                                </f:facet>
                                <h:outputText value="#{cliente.nomeFantasia}" />
                            </p:column>


                            <p:column style="width: 10px">                                                             
                                <p:commandButton image="ui-icon ui-icon-search"
                                                 title="Selecionar cliente"
                                                 action="#{buscaBean.selecionarCliente(cliente)}" ajax="false"/>
                            </p:column>
                        </p:dataTable>                    
                    </div>
                </h:form>
            </div>
        </div>
    </h:body>

Estou usando somente um form, como o Matruskan falou, mas mesmo assim não funciona.

Na verdade eu coloquei a página .xhtml na action para testar, mas não funcionou. Ele volta para a mesma página.
A idéia do sistema é listar o resultado da busca em uma tabela e o usuário selecionar o registro desejado clicando no botão
que eu coloquei em uma coluna no datatable. Com isso, o sistema irá para outra página onde irá ser mostrado as informações
desse cliente selecionado.

Quem tiver uma idéia melhor de como fazer isso, eu agradeço.

Abraço,
Diogo Dias


Francisco de Assis

unread,
Jun 18, 2011, 3:33:41 PM6/18/11
to javasf: JavaServer Faces Group
Olá Marcelo,

Caí de "gaiato" na conversa mas por que vi algo que me chamou atenção
em sua resposta;
Você falou sobre "paginação sob demanda". Eu fui acompanhando a
conversa por que tive um problema semelhante com dataTable do Prime
Faces.
No entanto o maior problema que tive na empresa onde trabalho foi um
sistema que desenvolvemos utilizando JSF 2.0 / Prime Faces / GlassFish
3.
Utilizamos métodos retornando as Strings das páginas para o
redirecionamento etretanto este sistema (Um emissor de recibos)
"permitia" (mas não devia) que o usuário navegasse pelo contexto e que
fizesse refresh (F5) causando a emissão em duplicidade dos recibos
entre outros refreshs indesejados.

Por acaso a "paginação sob demanda" tem a ver com isso, se tiver você
conhece algum flow ou padrão de desenvolvimento que garanta isso?

Agradçeo desde já sua atenção.

Francisco de Assis
chico...@gmail.com


On 17 jun, 14:50, Marcelo Preis Ferreira <preis.ud...@gmail.com>
wrote:

Matruskan

unread,
Jun 18, 2011, 2:30:57 PM6/18/11
to jav...@googlegroups.com
Boa tarde, Diogo,

1) Se o Bean como Request funcionou, há motivos para que ele não seja de Request?

Geralmente, beans de request oferecem a vantagem de não ocuparem memória no servidor depois que a requisição acaba. Também posso afirmar que sofri represálias no serviço quando tentei criar beans com outros escopos, hehehe. Talvez o pessoal possa, em outro tópico, discutir quando é melhor usar qual escopo...

Suponho que o que está acontecendo é:

Botão de busca -> bean pede a busca de clientes -> hibernate abre sessão -> busca realizada, clientes colocados em uma lista -> bean pega as informações necessárias dos 15 primeros clientes -> hibernate fecha sessão.
Botão do paginator -> bean pega os próximos 15 clientes de sua lista -> bean tenta pegar informações desses clientes, mas elas estão no BD e o hibernate fechou a sessão -> SessionException

Se for de Request, o bean vai pedir a busca de clientes pro hibernate sempre, então na hora de pegar as informações, a sessão do hibernate estará sempre aberta.


2) Eu já usei o EL para passagem de parâmetros com o Tomcat 6 colocando o EL correto na biblioteca do projeto (talvez eu tenha modificado algum pacote, não tenho certeza...).

Deve ser mais difícil achar servidores com Tomcat 7 e deve ser mais caro os que tem Glassfish. Se o seu projeto não tiver problemas com o tipo de servidor que será usado, ou se for um projeto pessoal mesmo, acho que vale a pena usar os mais recentes, pelas facilidades que eles oferecem.

De qualquer forma, como você disse que está utilizando o Glassfish e ainda não funcionou, tente utilizar o código antigo (o primeiro que você mandou), mas coloque parênteses no método chamado no action e adicione ajax="false". Talvez funcione.
(fonte: http://stackoverflow.com/questions/4537678/jsf-pdatatable-pcommandbutton-doesnt-work-even-inside-pcolumn )


2011/6/17 Diogo Dias <diogo....@gmail.com>

Marcelo Preis Ferreira

unread,
Jun 20, 2011, 8:00:40 AM6/20/11
to jav...@googlegroups.com
Francisco,

O que me parece a respeito do seu problema tem erros de programação e requisitos.
assim, acredito que você deveria ter uma propriedade no teu recibo, verificando se ele já foi impresso.
e uma opção para o usuário re-imprimir, caso o usuário deseje.

E outro ponto pode ser também você limpar o objeto, depois que ele foi impresso.
E um terceiro você poderia desativar a pagina ou refresh, não sei como fazer isso, mas, sei que tem como fazer.

Diogo Dias

unread,
Jun 20, 2011, 10:20:20 AM6/20/11
to jav...@googlegroups.com
Boa tarde, matruskan.

Ele funciona como Resquest se eu colocar no método que recupera a lista, uma lista já pre definida.
Se chamar a action do botão de busca, e popular a lista associada ao datatable, o datatable só mostra os 15 primeiros registros.
e quando eu clico no paginator ele não traz nada. 

Mas beleza, dei uma olhada no link que você e é exatamente esse problema que eu estou tendo. Vou tentar fazer o que o cara 
fez e ver se da certo e dou um retorno aqui.

Value cara, obrigado.

Att,
Diogo

Francisco de Assis

unread,
Jun 20, 2011, 10:42:49 PM6/20/11
to javasf: JavaServer Faces Group
Olá Marcelo,

O que você disse está correto. Este projeto já se foi. Tivemos muitos
problemas e uma outra equipe que faz parte do mesmo escritório acabou
por desenvolvê-lo com Jboss Seam.
Entretanto os erros aconteceram desde a entrega dos requisistos.
Infelizmente temos um Gestor que não entende muita coisa sobre
desenvolvimento.
Ficamos a mercê de documentação "fraca" e a falta de alinhamento da
equipe contribuiu para o não desenvolvimento do projeto.
Eu continuo pesquisando e estudando para aprender as melhores práticas
para o desenvolvimento. Comecei a desenvolver web e desktop a pouco
tempo (1 ano) e o desafio é grande, a quantidade de informação é
tremenda. Enfim, sigo buscando.

Agradeço por seu retorno.

Francisco

On 20 jun, 09:00, Marcelo Preis Ferreira <preis.ud...@gmail.com>
wrote:

Marcelo Preis Ferreira

unread,
Jun 21, 2011, 1:40:55 PM6/21/11
to jav...@googlegroups.com
Francisco,

Lamento pelo seu projeto.
Se for do interesse da sua empresa eu presto consultoria nesta área
me envie um  email particular para tratarmos o assunto

Tenho quase 4 anos de exeperiência e acredito em uma premissa, para se ter as respostas certas.
Só precisa fazer as perguntas certas, mas como fazer as perguntas certas?
nesse mar de informação que chega a todo instante em sua porta.

Me perdoe o dono da Thread, o Sr.Diogo
Precisamos aproveitar o que julgamos de novas oportunidades


Um abraço a todos!
Reply all
Reply to author
Forward
0 new messages