Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@PostConstruct of @ViewScoped is invoked on every request [duplicate]

I've got problem with opening dialog in JSF 2.2.7 and Primefaces 5. I've got button which opens a dialog and the problem is everytime when I click the button @PostConstruct method is executed. Why?

I want to invoke @PostConstruct only 1 time, but I don't want to change to scope to Session (with @SessionScope annotation it works perfectly).

It's my view:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:c="http://java.sun.com/jstl/core"
    xmlns:p="http://primefaces.org/ui">

<h:head>

</h:head>
<h:body>
    <h:form id="f1">
        <p:dialog widgetVar="trainingDialog2" id="d1">
            <h:outputText value="#{userViewBean.errorMessage}" />
        </p:dialog>
        <br />

        <p:dataTable id="dt1" value="#{userViewBean.infoList}" var="item">
            <p:column>
                <p:commandButton id="btn" update=":f1:d1"
                    oncomplete="PF('trainingDialog2').show()"
                    styleClass="ui-icon ui-icon-calendar">
                    <f:setPropertyActionListener value="#{item.id}"
                        target="#{userViewBean.errorMessage}" />
                </p:commandButton>
            </p:column>
        </p:dataTable>
    </h:form>
</h:body>
</html>

It's my bean:

package pl.jrola.java.www.vigym.viewcontroller.beans.userview;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.view.ViewScoped;

@ManagedBean(name = "userViewBean")
@ViewScoped
public class UserViewBean implements Serializable {

    private static final long serialVersionUID = 6994205182090669165L;

    private String errorMessage;

    private List<UserProfileInfoBean> infoList;

    public List<UserProfileInfoBean> getInfoList() {
        return infoList;
    }

    public void setInfoList(List<UserProfileInfoBean> infoList) {
        this.infoList = infoList;
    }


    public UserViewBean() {

    }

    @PostConstruct
    public void postConstruct() {
        this.infoList = new ArrayList<UserProfileInfoBean>();
        for (long i = 0; i < 3; i++) {
            this.infoList.add(new UserProfileInfoBean(i));
        }

    }


    public String getErrorMessage() {
        return errorMessage;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }


}
like image 919
jrola Avatar asked Aug 23 '14 13:08

jrola


People also ask

How many times a @PostConstruct method is called?

2. @PostConstruct. Spring calls the methods annotated with @PostConstruct only once, just after the initialization of bean properties. Keep in mind that these methods will run even if there's nothing to initialize.

When @PostConstruct is called in Java?

Methods marked with the @PostConstruct will be invoked after the bean has been created, dependencies have been injected, all managed properties are set, and before the bean is actually set into scope.

Why we use@ PostConstruct in spring boot?

When we annotate a method in Spring Bean with @PostConstruct annotation, it gets executed after the spring bean is initialized. We can have only one method annotated with @PostConstruct annotation. This annotation is part of Common Annotations API and it's part of JDK module javax.

What is@ PreDestroy annotation?

Annotation Type PreDestroy The PreDestroy annotation is used on methods as a callback notification to signal that the instance is in the process of being removed by the container. The method annotated with PreDestroy is typically used to release resources that it has been holding.


1 Answers

You're mixing the annotations for JSF beans and CDI beans, effectively making the bean @RequestScoped, because it's the default for a @ManagedBean.

If you use JSF beans use:

javax.faces.bean.ManagedBean;
javax.faces.bean.ViewScoped;

If you wanna go for CDI beans use:

javax.inject.Named;
javax.faces.view.ViewScoped;

If your server supports CDI you should go for CDI beans.

Read more about the default scopes here: What is the default Managed Bean Scope in a JSF 2 application?

like image 181
Jaqen H'ghar Avatar answered Sep 28 '22 05:09

Jaqen H'ghar