JSF E O PROBLEMA DE N CHAMADAS A UM MÉTODO GETTER
- 2o MAU HABITO DOS DESENVOLVEDORES JSF (http://www.slideshare.net/tarsobessa/os-10-maus-hbitos-dos-desenvolvedores-jsf)
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.
http://stackoverflow.com/questions/2090033/why-jsf-calls-getters-multiple-times
http://stackoverflow.com/questions/4281261/why-is-the-getter-called-so-many-times-by-the-rendered-attribute
http://seamframework.org/Documentation/WhyDoesJSFCallMyGetterHundredsOfTimes