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 a 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 (Mojarra ou MyFaces)!
Um componente de iteração como h:dataTable ou ui:repeat são os campeões nisso! Além da lista (neste caso cargos) todos os componentes internos do ht:dataTable que possuem EL são executados diversas vezes dependendo do número de linhas e colunas.
Enfim, a boa prática é: Não coloque processamento custoso nos métodos 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 utilizando 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<Cargo> 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.