2

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 ?

  • If you debug `utente = ejbFacade.setUtente(user);` line, is `utente` not null? I'd say the method `setUtente(...)` either is wrong named (you are trying to ***get*** an entity from EJB) or is not the appropriate method given your code. – dic19 Oct 08 '14 at 14:46
  • utente is not null. It has all the right field value. Which is the right way to an entity from a DB table ? I though that get it from EJB facade was the best way.... I added the code sequence above @dic19 – Claudio Cerino Oct 08 '14 at 14:53
  • The way is right, but I'd rename `setUtente(...)` to `getUtentePerNome(...)` since that's what the method actually does. Everything in your code looks fine and should work ok, I don't see nothing strange. Note there's a missing `` tag in your `beans.xml` but I think it's just a copy-paste issue. – dic19 Oct 08 '14 at 15:17
  • I rename the method as you suggest. But the app doesn't work. Is there something that i have to configure in glassfish or in Netbeans ? Where I've to put the beans.xml file ? I've put it in WEB-INF folder, is it right ? Is the PostConstruct be a problem ? – Claudio Cerino Oct 08 '14 at 15:42
  • Please my beans.xml example. You can auto-generate this file in NetBeans. – dic19 Oct 08 '14 at 15:53
  • Done and it doesn't work. Always the same.... – Claudio Cerino Oct 08 '14 at 16:03
  • Obviously I test another basic app that work in the same way and all works fine. This is an informatic mistery !!!! – Claudio Cerino Oct 08 '14 at 16:34
  • Yes, this things just happen... As I've said it all looks good to me. Hope you can solve it! :D – dic19 Oct 08 '14 at 19:43

1 Answers1

3

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>
Community
  • 1
  • 1
dic19
  • 17,446
  • 6
  • 35
  • 64
  • Thank you for your answer. Now I know that there is a difference between Named and ManagedBean. But the problem persist ! Now, after replace ManagedProperties with Inject, and create a blank beans.xml file, when debug the code, i see the variables that contains the injected UserController has all null fields. There something i should change ? It seems to be a new istance of UserController, not the first that I istanciated. Thanks again for your replies. – Claudio Cerino Oct 08 '14 at 07:24
  • Well the good news is injection is working. Note that you don't have to explicitely instatiate nothing because both beans are managed. If `UserController` looks like a new instance is because the container didn't create an instance before (because it wasn't needed). It's hard to give you a specific answer withouth knowing the flow in your application. Maybe you can post the sequence in what your beans are being called, not just their definition. @ClaudioCerino – dic19 Oct 08 '14 at 11:39
  • I have edit the question with the code sequence. I hope you can illuminate me. Thanks again @dic19 – Claudio Cerino Oct 08 '14 at 14:29