Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

Edição em DataTable PrimeFaces.

Olá, estou tentando utilizar o datatables do Primefaces, mas tenho dificuldades em entender porque ocorre várias chamadas no get que constrói a tabela e como corrigir isso.

view:

<h:form>
           <p:panel>     
                <p:dataTable value="#{datasbean.todasasdatas}" var="d"  editable="true" id="tabeladatas" 
                    emptyMessage="Não há datas Cadastradas">
                    <f:facet name="header">  
                        Lista de Datas 
                    </f:facet>

                    <p:ajax event="rowEditInit" listener="#{datasbean.iniciaredicao}"/>
                    <p:ajax event="rowEdit" listener="#{datasbean.alterar}" update=":form1:messages" />                     
                    <p:ajax event="rowEditCancel" listener="#{datasbean.cancelar}" update=":form1:messages" /> 

                    <p:column>
                        <f:facet name="header">  
                            <h:outputText value="Ano" />  
                        </f:facet>
                        <p:cellEditor>  
                            <f:facet name="output">  
                                <h:outputText value="#{d.tbano.ano}" />  
                            </f:facet>  
                            <f:facet name="input">  
                                <p:inputText value="#{datasbean.tbano.ano}" style="width:100%"/>
                            </f:facet>  
                        </p:cellEditor> 
                    </p:column>

                    <p:column>
                        <f:facet name="header">  
                            <h:outputText value="Descrição" />  
                        </f:facet>
                        <p:cellEditor>  
                            <f:facet name="output">  
                                <h:outputText value="#{d.descricao}" />  
                            </f:facet>  
                            <f:facet name="input">  
                                <p:inputText value="#{datasbean.dtdescricao}" style="width:100%"/>  
                            </f:facet>  
                        </p:cellEditor> 
                    </p:column>

                    <p:column>
                        <f:facet name="header">  
                            <h:outputText value="Inicio" />  
                        </f:facet>
                        <p:cellEditor>  
                            <f:facet name="output">  
                                <h:outputText value="#{d.datainicio.time}">
                                    <f:convertDateTime pattern="dd/MM/yyyy HH:mm:ss" timeZone="GMT-03:00"/> 
                                </h:outputText>  
                            </f:facet>  
                            <f:facet name="input">  
                                    <p:calendar id="datainicio" value="#{datasbean.datainicio}" pattern="dd/MM/yyyy HH:mm:ss" timeZone="GMT-03:00"/> 
                            </f:facet>  
                        </p:cellEditor>
                    </p:column>

                    <p:column>
                        <f:facet name="header">  
                            <h:outputText value="Termino" />  
                        </f:facet>
                        <p:cellEditor>  
                            <f:facet name="output">  
                                <h:outputText value="#{d.datafim.time}">
                                    <f:convertDateTime pattern="dd/MM/yyyy HH:mm:ss" timeZone="GMT-03:00"/> 
                                </h:outputText>  
                            </f:facet>  
                            <f:facet name="input">  
                                    <p:calendar id="datafim" value="#{datasbean.datafim}" pattern="dd/MM/yyyy HH:mm:ss" timeZone="GMT-03:00"/>

                            </f:facet>  
                        </p:cellEditor>
                    </p:column>
                    <p:column>
                        <f:facet name="header">  
                            <h:outputText value="Tipo" />  
                        </f:facet>
                        <p:cellEditor>
                            <f:facet name="output"><h:outputText value="#{d.tbtipo.descricao}" /></f:facet>
                            <f:facet name="input">
                               <h:selectOneMenu value="#{datasbean.tbtipo.id}" style="width:100%">
                                   <f:selectItems value="#{datasbean.listatipos}" var="tipo" itemLabel="#{tipo.descricao}" itemValue="#{tipo.id}" />
                               </h:selectOneMenu>
                           </f:facet>
                        </p:cellEditor>   
                    </p:column>


                    <p:column headerText="Editar" style="width:70px">  

                        <p:rowEditor/>

                    </p:column>

                    <p:column headerText="Remover" style="width:70px">
                     <p:commandLink styleClass="ui-icon ui-icon-trash" action="#{datasbean.remover}" value="Remover" update="tabeladatas">                           
                                <f:setPropertyActionListener target="#{datasbean.tbdata}" value="#{d}" /> 
                     </p:commandLink>                              
                   </p:column> 

                </p:dataTable>
            </p:panel>
             </h:form>

MB:

@ManagedBean(name="datasbean")
@ViewScoped
public class CalendarioBean implements Serializable{
/** omitido **/
private List<Tbdata> todasasdatas;

/** omitido **/

public List<Tbdata> getTodasasdatas() {
        return new TbdataDaoImpl().listarDatas();
    }

    public void setTodasasdatas(List<Tbdata> todasasdatas) {
        this.todasasdatas = todasasdatas;
    }
/** omitido **/

Quando aciono a edição de uma linha da tabela o método "getTodasasdatas "que constrói a tabela é chamado diversas vezes . Isso é normal ? Ou existe alguma configuração que falta adicionar?

Obrigado.

7 respostas

Isso é esperado, uma característica da deffered expression language, a #.

Você pode saber mais em :

http://stackoverflow.com/questions/2090033/why-jsf-calls-getters-multiple-times

Há uma forma já conhecida e bem batida para contornar esse problema:

@ManagedBean(name="datasbean")
@ViewScoped
public class CalendarioBean implements Serializable{

    private List<Tbdata> todasasdatas;


    public List<Tbdata> getTodasasdatas() {
        if(todasasdatas == null) {
            this.todasasdatas = new TbdataDaoImpl().listarDatas();
        }
        return this.todasasdatas;
    }
}

Quando o JSF for chamar mais de uma vez o método getTodasasdatas ele só chamará uma vez durante a requisição.

Abraço!

Entendi, já tinha visto esta solução. Mas achei que fosse um erro mesmo. Mas nesta solução, se existir uma outra atualização do banco de dados em outra sessão, a tabela ficaria desatualizada mesmo né? Existe alguma outra forma?

Ficaria, mas se você quer sempre atualizada, deixe do jeito que estava, certo?

Abraço!

Entendi, mas se ficar do jeito que está varias chamadas ao banco são feitas desnecessariamente. Seria possível colocar algum datatable ou alguma outra solução que evite isso (além da já citada)?

Se você usa cache de segundo nível com JPA isso não será problema, porque ele não irá até o banco. Mas JPA e cache de segundo nível é fora do escopo de JSF, mas sugiro que você dê uma pesquisa. Se não usa JPA e usar JDBC, ai é essa solução mesmo que sugerir, a anterior.

Abraço

Entendi, apenas estou complementando os estudos. Não é uma aplicação que vai para produção, apenas tentando entender como funciona o JSF. Mas a dica do JPA está valendo, talvez possa usar em outra ocasião também.

Muito obrigado pela ajuda Flávio.

solução!

Tranquilo Fábio, só não pare de estudar....

Abraço e bom final de semana!