Ainda não tem acesso? Estude com a gente! Matricule-se
Ainda não tem acesso? Estude com a gente! Matricule-se

ViewScoped sendo criado muitas vezes

Adicionei ao meu Bean, a anotação @PostConstruct para exibir uma mensagem sempre que for criado.

@Named // import javax.inject.Named;
@ViewScoped // import javax.faces.view.ViewScoped;
public class BrandBean implements Serializable {

    private static final long serialVersionUID = 9204486797916777869L;

    @Inject
    private BrandService brandService;

    @PostConstruct
    public void init() {
        System.out.println("Creating BrandBean");
    }
}

Porém, ao abrir a página, ele cria o Bean duas vezes. Ao ordenar os elementos do datatable, o Bean é criado 11 vezes. Ao editar um campo, é criado mais algumas vezes. Ou seja, ele não está guardando meu escopo corretamente, é como se o @ViewScoped não estivesse ali.

Quando altero para @ApplicationScoped, está tudo funcionando em ordem, ou seja, o CDI está configurado corretamente. Porém, não está no contexto que eu gostaria que estivesse: RequestScoped é muito pouco, e @ApplicationScoped é muito.

Meu beans.xml foi criado pelo próprio Red Hat Studio, durante a configuração.

<?xml version="1.0"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
    version="1.2" bean-discovery-mode="all" />

Estou utilizando as seguintes configurações: javaee-api = 7.0 javax.faces-api = 2.2 (provided) cdi-api = 1.2 (provided) weld-servlet = 2.3.5 (provided) Jboss EAP 6.3 Java 7

Tenho também o problema da configuração do namespace do JSF 2.2, mas não consigo identificar se é problema de incompatibilidade de versão ou outra configuração que tenho que realizar.

Eu preciso de um auxílio para entender como começar a verificar estes erros, visto que tirando os novos namespaces e o @ViewScoped, o projeto funciona corretamente.

Obrigado deste já!

7 respostas

Fala Giovane, tudo bem?

O que acontece é que no ciclo de vida do JSF, esse objeto é instanciado diversas vezes. O fato de ser viewScoped não interfere no valor do objeto pois durante o ciclo de vida, os valores dos atributos do objeto estão na árvore de componentes e são colocados no objeto na hora que o JSF e/ou o CDI precisarem dele.

Opa Samir, tudo certo e contigo?

Entendo que ele pode ser criado diversas vezes, mas ele não está aguardando o valor do objeto durante minhas requisições naquela View. Pois quando, por exemplo, eu tento ordenar um datatable, ele não o faz e cria uns 8 Beans com os valores "zerados". Apenas quando troco para "ApplicationScoped" que ele começa a fazer tudo nos conformes.

Por isso não estou entendendo muito bem que tipo de configuração estou fazendo errado...

Oi Giovane, vc pode passar o codigo da sua view e o código do bean?

Seguem arquivos:

index.xhtml

BrandBean.java

Obrigado deste já pela força!

fala Giovane, feliz ano novo!!

desculpa a demora! Faz o seguinte, tenta dar um new no objeto Brand na declaração dele e não chama o clean no PostConstruct. Veja se isso resolve o problema.

Samir, tive uma esperança muito grande quando li seu comentário. Fez tanto sentido que parecia que não ia dar errado.

Mas realmente não deu certo ainda, como no outro problema vou testar outras versões e servidores de aplicação para ver se o problema persiste. Obrigado!

Antigamente existia um bug relacionado ao evento preRenderView onde acontecia a mesma coisa e se resolvia adicionando a tag um parametro vazio outra coisa é verificar se o request não é um postback, mas pra se ver realmente livre desses problemas e se é preciso que o jsf execute um código no momento de uma página ser exibida eu sugiro fortemente que use viewAction

<f:metadata>
    <f:viewParam id="id" name="item" value="#{catalog.item}"/>
    <f:viewAction action="#{catalog.checkItem}"/>
</f:metadata>
@Named
@ViewScoped
public class Catalog implements Serializable {

    private Integer item;
    private FacesContext facesContext;

    public String checkItem() {
        if (item.intValue() >= range.getLow() && 
            item.intValue() <= range.getHigh()) {
            return null;
        }
        facesContext.addMessage(null, 
            new FacesMessage("The item number you entered is invalid."));
        return "index";
    }
}

eu só uso view action e parei de ter esse tipo de problema