jsfnetbeanspostconstructmanaged-property

JSF @managedproperty and @PostConstruct


I have a problem with JSF2 @ManagedProperty annotation. I have a managed bean that create a user, then i want to pass this user to another bean to display other informations relative to that user. So my code is below :

@Named("userController")
@SessionScoped
public class UserController implements Serializable {

@EJB
private session.UserFacade ejbFacade;
private List<User> items = null;
private User selected;
private User utente;
private String user;
private String pass;
----getter and setter----

In the Schedule Bean I use the userController bean in the @PostConstruct :

@Named(value = "scheduleController")
@SessionScoped
public class ScheduleController implements Serializable {

private ScheduleModel eventModel;  

private ScheduleEvent event = new DefaultScheduleEvent();

@EJB
ActivityFacade ejbFacade;

@ManagedProperty(value="#{userController}")
private UserController credentials;


public ScheduleController() {        
}

@PostConstruct
public void init(){
    eventModel = new DefaultScheduleModel();       
    List<Activity> daFare =ejbFacade.findForUser(credentials.getUtente().getIdUser());
    for(int i=0;i<daFare.size();i++){
        eventModel.addEvent(new DefaultScheduleEvent(daFare.get(i).getDescrizione(),daFare.get(i).getDalleOre(),daFare.get(i).getAlleOre() ));
    }
}

public void setCredentials(UserController credentials) {
    this.credentials = credentials;
}   

When i debug the code, I see that the UserController credentials is always null.... What's wrong ? I need to specify something in faces-config.xml ? Thanks a lot for your tips.

EDIT :

After change @ManagedProperty with @Inject and after add the below beans.xml in WEB-INF folder, the problem persist.

<?xml version="1.0" encoding="UTF-8"?>
   <beans xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">

The app work in this way: A user can log in via this xhtml page:

<body>
    <h:form>  
        <p:growl id="msgs" showDetail="true" />
        <p:panel header="Inserisci i tuoi dati" style="margin: 0 auto; text-align: center" >
            <h:panelGrid columns="2" cellpadding="5" style="margin: 0 auto; text-align: center">
                <p:outputLabel value="Username"/>
                <p:inputText value="#{userController.user}"  required="true" label="Username"   size="40"/>
                <p:outputLabel value="Password" />
                <p:password  value="#{userController.pass}"  required="true" label="Password" size="40"/>
                <p:commandButton action="#{userController.validateLogin}" value="Login"  update="msgs" ajax="false" style="text-align: center"/>
            </h:panelGrid>
        </p:panel>         
    </h:form>

</body>

After submit the form, the userController verify that this specific user exist in a DB table and then instantiate the User utente ( id, username, password, email as field ). After this, the app redirect to home.xhtml that display several user's information and select several information of a DB table selected by user's id. Here is the code where I set User utente:

public String validateLogin(){

    String output="home";
    boolean exist=false;
    exist=ejbFacade.logValid(user,pass);
    if(!exist){
        //FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Username o Password errata","Contattare l'amministratore"));             
        return "index";
    }else{
        utente=ejbFacade.setUtente(user);  
        FacesContext context = FacesContext.getCurrentInstance();          
        context.addMessage(null, new FacesMessage("Accesso eseguito con successo.","Bentornato " + user));
        return output;
    }
}

The code sequence in which i control the existece of a user and set the utente is:

@Stateless
public class UserFacade extends AbstractFacade<User> {
@PersistenceContext(unitName = "ImmobiliareWebPU")
private EntityManager em;

@Override
protected EntityManager getEntityManager() {
    return em;
}

public UserFacade() {
    super(User.class);
}

public boolean logValid(String user, String pass) {
    List<User> utente ;
    boolean autorizzato;
    String find = "User.findByUsername&Password";
    Query query = em.createNamedQuery(find, User.class);
    query.setParameter("username", user);
    query.setParameter("password", pass);
    utente =query.getResultList();
    if (utente.isEmpty()) {
        autorizzato=false;           
    }
    else{
       autorizzato=true;                      
    }
    return autorizzato;
}

public User setUtente(String user) {
    //SETTO L'UTENTE PER LA SESSIONE DEL PROGRAMMA
    User utente;
    String find = "User.findByUsername";
    Query query = em.createNamedQuery(find, User.class);
    query.setParameter("username", user);       
    utente =(User) query.getSingleResult();

    return utente;
}

}

the code where I need user's information is :

@Named(value = "scheduleController")
@RequestScoped
public class ScheduleController implements Serializable {

private ScheduleModel eventModel;  

private ScheduleEvent event = new DefaultScheduleEvent();

@EJB
ActivityFacade ejbFacade;

@Inject
private UserController credentials;


public ScheduleController() {        
}

@PostConstruct
public void init(){
    eventModel = new DefaultScheduleModel();       
    List<Activity> daFare =ejbFacade.findForUser(credentials.getUtente().getIdUser());
    for(int i=0;i<daFare.size();i++){
        eventModel.addEvent(new DefaultScheduleEvent(daFare.get(i).getDescrizione(),daFare.get(i).getDalleOre(),daFare.get(i).getAlleOre() ));
    }
}

In the ejbFacade i make a simple query :

@Stateless
public class ActivityFacade extends AbstractFacade<Activity> {
@PersistenceContext(unitName = "ImmobiliareWebPU")
private EntityManager em;

@Override
protected EntityManager getEntityManager() {
    return em;
}

public ActivityFacade() {
    super(Activity.class);
}

public List<Activity> findForUser(int utenteId) {
    //RICHIEDO LE ATTIVITA' DEL SINGOLO UTENTE
    List<Activity> daFare ;
    String find = "Activity.findByUserId";
    Query query = em.createNamedQuery(find, Activity.class);
    query.setParameter("idUser", utenteId);
    daFare =query.getResultList();

    return daFare;
}

}

In debug mode i see an istance of UserController with all null fields; it seems to be a new istance of UserController. I use also "import javax.enterprise.context.SessionScoped" . Where is my fault ?


Solution

  • When i debug the code, I see that the UserController credentials is always null.... What's wrong?

    Please note you are mixing up CDI (Context and Dependency Injection) with Managed properties, which is probably causing the described behavior. Your beans are annotated with @Named instead of @ManagedBean so this:

        @ManagedProperty(value="#{userController}")
        private UserController credentials;
    

    Should be replaced by this:

        @Inject
        private UserController credentials;
    

    For a really great explanation about the difference between CDI and backing beans see @BalusC answer in this topic: Backing beans (@ManagedBean) or CDI Beans (@Named)?.


    I need to specify something in faces-config.xml?

    No, but you should include a beans.xml like exemplified here: Packaging CDI applications. As far as I remember this file is mandatory regardless the discovery mode. Here is the beans.xml that you can auto-generate in NetBeans:

    New file --> Context and Dependency Injection --> beans.xml (CDI Configuration file).

    This is all I've ever needed to make CDI work:

    <?xml version="1.0" encoding="UTF-8"?>
    <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"
           bean-discovery-mode="annotated">
    </beans>