Skip to content

Instantly share code, notes, and snippets.

@rponte
Last active December 31, 2015 15:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rponte/594131 to your computer and use it in GitHub Desktop.
Save rponte/594131 to your computer and use it in GitHub Desktop.
JSF invoking multiples times the same method getter

JSF E O PROBLEMA DE N CHAMADAS A UM MÉTODO GETTER

Imagine que o método abaixo possui um value-binding numa h:dataTable por exemplo.

public List<Cargo> getCargos() 
    return service.findAll(); // processo custoso
}

O método acima pode e provavelmente irá ser chamado diversas vezes durante uma requisição. O que está acontecendo é perfeitamente esperado, a própria especificação comenta sobre essa possibilidade. O número de vezes que um método getter é chamado não depende somente do número de vezes que uma EL é declarada (aparece) na página. Ele também depende do ciclo de vida (que pode chama-lo quantas vezes for necessário) e do componente que tem a referência a esta EL.

Por exemplo, um h:inputText pode ter sua EL chamada de 2 ou 4 vezes ou até mais durante o ciclo de vida (conversão, validação, t:saveState etc). E isso pode variar para mais ou menos dependendo da implementação do JSF que está em uso!

Um componente de iteração como h:dataTable ou ui:repeat são os campeões nisso. Além da lista (no seu caso cargos) todos os componentes internos que possuem EL são executados diversas vezes dependendo do número de linhas e colunas.

Enfim, a dica é: Não coloque processamento custoso nos teus getters, pois isso é uma má prática se tratando de JSF. Se for realmente necessário então garanta ao menos que o processamento somente será executado uma vez por request.

Você consegue isso utilizendo um calllback como @PostConstruct ou carregue a lista de cargos em um método disparado por um evento de um componente (h:commandButton por exemplo).

Se for necessário que o código fique no getter então faça algo do tipo: public List getCargos() { if (cargos == null) cargos = service.findAll(); return cargos; }

O código acima garante que o .findAll() será executado somente uma vez numa mesma requisição.