[quote=grinche]Nunca popule um objeto dentro do método get, pois a cada requisição feita ao seu ManagedBean ele vai entrar no método get.
Crie uma propriedade no seu ManagedBean e também um método que vai popular este objeto, anote este método como PostConstruct, e então popule este e outros objetos neste método “inicial”. http://docs.oracle.com/javaee/5/api/javax/annotation/PostConstruct.html
Ou no seu xhtml utilize este evento para chamar um método que popula esta sua propriedade do managedBean.
[]'s[/quote]Não é uma boa idéia ser tão radical.
Já ouviu falar de lazy get? Você colocando no @PostConstruct toda vez que o MB for criado a consulta será executada mesmo que não venha a ser necessária.
O Lazy get funciona como eu postei acima, utilizando um if(atributo == null). Desse modo você irá executar apenas uma vez, pois após a primeira vez o atributo já estará populado.
Existe realmente as duas abordagens. Cada uma tem sua vantagem e desvantagem, mas nenhuma não deve ser taxada como “NOT TO USE”.
[quote=grinche]São os ciclos de vida do jsf, ele vai acessas seus métodos get várias vezes.
De uma olhada neste link abaixo, que você vai entender melhor.
[quote=Hebert Coelho][quote=grinche]Nunca popule um objeto dentro do método get, pois a cada requisição feita ao seu ManagedBean ele vai entrar no método get.
Crie uma propriedade no seu ManagedBean e também um método que vai popular este objeto, anote este método como PostConstruct, e então popule este e outros objetos neste método “inicial”. http://docs.oracle.com/javaee/5/api/javax/annotation/PostConstruct.html
Ou no seu xhtml utilize este evento para chamar um método que popula esta sua propriedade do managedBean.
[]'s[/quote]Não é uma boa idéia ser tão radical.
Já ouviu falar de lazy get? Você colocando no @PostConstruct toda vez que o MB for criado a consulta será executada mesmo que não venha a ser necessária.
O Lazy get funciona como eu postei acima, utilizando um if(atributo == null). Desse modo você irá executar apenas uma vez, pois após a primeira vez o atributo já estará populado.
Existe realmente as duas abordagens. Cada uma tem sua vantagem e desvantagem, mas nenhuma não deve ser taxada como “NOT TO USE”.[/quote]
Com certeza, você tem razão cado caso é um caso rsrsrs
Mas acredito eu que a melhor solução para o problema dele é utilizar o evento preRenderView.
Sei que a pergunta pode parecer ignorante, mas me intrigou:
Só pelo fato de eu colocar o nome do método iniciando com get ele chama diversas vezes?
Eu faço uma verificação de conteudo nulo sim dentro de um if e ele só executa a consulta se o conteúdo não for null ou não for empty.[/quote]Não.
O método ele é chamado por que na tela (xhtml/jsp) tem algum componente apontando para o método. O JSF precisa fazer várias verificações/utilizações e o primefaces também.[/quote]
Mas na xhtml o método esta instanciado em um commandButton, então entendo que ele só é executado quando acionado. Estou correto?[/quote]
Entenda o seguinte. get/set é padrão de nomeclatura javabeans.
O JSF não olha e fala: “ih tem um método que começa com get. Vou invocá-lo!”
Faça um teste, crie um método chamado getNaoVouSerChamado e coloque no MB, mas em nenhum momento aponte algum componente para ele. E você verá que ele não será chamado.
[quote=grinche]Não! Todo método que inicia com o nome get vai ser chamado a cada requisição.
[/quote]Eu fiz esse teste aqui e não funciona com você disse.
Eu utilizei o Mojarra 2.1.12
Qual o cenário que você consegue criar para afirmar isso?
[quote=Hebert Coelho][quote=grinche]Não! Todo método que inicia com o nome get vai ser chamado a cada requisição.
[/quote]Eu fiz esse teste aqui e não funciona com você disse.
Eu utilizei o Mojarra 2.1.12
Qual o cenário que você consegue criar para afirmar isso?[/quote]
:shock:
Até onde eu sei, se o atributo não está setado como value (e outro detalhe, o atributo sequer precisa existir, somente os get/set são suficientes), o método não é invocado.
Você ta certo, quis passar a mensagem de que é pra ele não usar isso e acabei falando besteira.
Sempre que tu for atualizar uma região onde tenha um elemento jsf se referenciando a uma propriedade de seu ManagedBean o método get vai ser chamado.
E no caso dele onde no seu método get ele vai a banco isso não é necessário pois ele só quer carregar na primeira vez que o usuário entrar na sua página.
[quote=grinche]Você ta certo, quis passar a mensagem de que é pra ele não usar isso e acabei falando besteira.
Sempre que tu for atualizar uma região onde tenha um elemento jsf se referenciando a uma propriedade de seu ManagedBean o método get vai ser chamado.
E no caso dele onde no seu método get ele vai a banco isso não é necessário pois ele só quer carregar na primeira vez que o usuário entrar na sua página.
[/quote]Exato.
Por isso eu falei do get com if (== null).
Bem, fica ao critério dele escolher uma abordagem.
Mesmo assim, acho errado fazer isso, tu vai precisar fazer uma validação a cada vez que entrar no método get.
Utilizando as outras soluções isso não é necessário.
[quote=grinche]Mesmo assim, acho errado fazer isso, tu vai precisar fazer uma validação a cada vez que entrar no método get.
Utilizando as outras soluções isso não é necessário.
[]'s[/quote]Como eu disse, cada abordagem tem sua vantagem e desvantagem.
SE você for entrar em uma tela que utilize o mesmo MB mas não utilize a lista. Você acha correto carregar a lista desnecessariamente?
[quote=grinche]Claro que não. Por isso a utilização do preRenderView no qual você so adiciona na tela em que quer carregar a lista.[/quote]Mas se o método com postconstruct carrega 3 informações do banco de dados. Como que essa anotação vai fazer com que o método anotado com postconstruct carregue apenas a informação necessária?
O evento de preRenderView não é uma anotação e nem postConstruct. É um evento do jsf no qual você chama um método no seu managedbean.
Como se for um onload do body mas que te possibilita a chamar um método no managedBean antes de construir a pagina.
[quote=grinche]Mesmo assim, acho errado fazer isso, tu vai precisar fazer uma validação a cada vez que entrar no método get.
Utilizando as outras soluções isso não é necessário.
[]'s[/quote]
Então não estamos falando de @Postconstruct mais. Você falou soluções, estava trabalhando em cima dele.
[quote=grinche]O evento de preRenderView não é uma anotação e nem postConstruct. É um evento do jsf no qual você chama um método no seu managedbean.
Como se for um onload do body mas que te possibilita a chamar um método no managedBean antes de construir a pagina.[/quote]
A idéia de utilizar o f:event é legal.
Volto a dizer, é questão de gosto. [=
com o f:event você vai ter que ter um método a mais para isso, mas funciona do mesmo modo.
Valeu Pessoal. Estudando um pouco mais sobre o ciclo de vida do JSF e sobre os 10 “maus hábitos” dos desenvolvedores JSF (Rafael Ponte e Tarso Bessa) http://www.slideshare.net/tarsobessa/os-10-maus-hbitos-dos-desenvolvedores-jsf, pude compreender melhor o que o grinche e o Herbert Coelho estavam tentando me explicar. Vi que o problema estava na forma em que eu invocava um List com get para preencher um dataTable. Isso gerava uma carga de consulta sem necessidade.
Para ajudar os que estão com essa mesma dificuldade oriunda dos péssimos hábitos adquiridos nos cursos de JSF1.2 (eu), postarei abaixo como deverá ficar uma consulta filtrada no bean e no jsf. Aos amigos, se eu estiver errado, podem me corrigir.
[code]…
//método getList convencional
public List getEnderecos() {
return this.enderecos;
}
//método que será invocado na action do commandButton:
public void carregaEnderecos() {
//popule a lista por aqui
this.enderecos = dao.populealista(campo);
}
//LÁ NO JSF, vc deve atribuir a lista convencional no dataTable
<p:dataTable id=“ListEnderecos” var=“enderecos” value="#{enderecoBean.enderecos}" …
[/code]
Agradeço a ajuda de todos, principalmente do grinche e do Herbert Coelho.
Valeu Pessoal. Estudando um pouco mais sobre o ciclo de vida do JSF e sobre os 10 “maus hábitos” dos desenvolvedores JSF (Rafael Ponte e Tarso Bessa) http://www.slideshare.net/tarsobessa/os-10-maus-hbitos-dos-desenvolvedores-jsf, pude compreender melhor o que o grinche e o Herbert Coelho estavam tentando me explicar. Vi que o problema estava na forma em que eu invocava um List com get para preencher um dataTable. Isso gerava uma carga de consulta sem necessidade.
Para ajudar os que estão com essa mesma dificuldade oriunda dos péssimos hábitos adquiridos nos cursos de JSF1.2 (eu), postarei abaixo como deverá ficar uma consulta filtrada no bean e no jsf. Aos amigos, se eu estiver errado, podem me corrigir.
[code]…
//método getList convencional
public List getEnderecos() {
return this.enderecos;
}
//método que será invocado na action do commandButton:
public void carregaEnderecos() {
//popule a lista por aqui
this.enderecos = dao.populealista(campo);
}
//LÁ NO JSF, vc deve atribuir a lista convencional no dataTable
<p:dataTable id=“ListEnderecos” var=“enderecos” value="#{enderecoBean.enderecos}" …
[/code]
Agradeço a ajuda de todos, principalmente do grinche e do Herbert Coelho.