@javax.faces.bean.ManagedProperty in CDI @Named bean returns null
Asked Answered
E

1

22

I'm trying to deal with @javax.faces.bean.ManagedProperty but without success !

I've been following this guide, and it not seems that hard. But my code simply won't work!

Here's a little snippet

@ManagedBean
@SessionScoped
public class LoginBean {

    private User user;

    // ...
}
@Named
@RequestScoped
public class MessagesBean {

    @ManagedProperty(value = "#{loginBean}")
    private LoginBean loginBean;

    public String getUser() {
        System.err.println(loginBean == null);
        return loginBean.getUser().getUsername();
    }

    // ...
}

This code gives me a NullPointerException, saying that loginBean is null!

Any suggestion?

Emulation answered 29/3, 2012 at 8:0 Comment(1)
Does @EJB annotation automatically inject the bean, or how do you inject them to LoginBean ?Skiascope
M
44

You are mixing JSF managed beans with CDI beans. Your LoginBean is a JSF managed bean (it has the @ManagedBean annotation). Your MessageBean is a CDI bean (it has the @Named annotation). If you changed the Message bean to a JSF managed bean (replacing @Named with @ManagedBean) then the problem should be solved (It should work with two CDI beans as well). Or if you're using JSF 2.3 or newer, then use javax.faces.annotation.ManagedProperty instead in the CDI bean.

Here is a short overview of how injection works between both bean types:

CDI @Named --> CDI @Named (works)

CDI @Named --> JSF @ManagedBean (works only if scope of injected bean is broader)

JSF @ManagedBean --> JSF @ManagedBean (works only if scope of injected bean is broader)

JSF @ManagedBean --> CDI @Named (won't work)

But take care of the scope import classes. There are different classes for @SessionScoped and @RequestScoped depending on the bean type.

javax.faces.bean.SessionScoped for @ManagedBeans

javax.enterprise.context.SessionScoped for CDI @Named beans

In addition, for @Named (CDI) use @Inject and for @ManagedBean use @ManagedProperty. There is one thing that does not work in CDI. Your @ManagedProperty(value = "#{loginBean}") gets a full bean, but @ManagedProperty(value = "#{loginBean.user}") to get a 'property' of a bean works to. This is not directly possible in CDI with @Inject. See CDI Replacement for @ManagedProperty for a 'solution'

Malapert answered 29/3, 2012 at 8:10 Comment(4)
Great, thanks ! I already tried replacing @Named with @ManagedBean, but I had the wrong @RequestScoped annotation import, so it didn't work!Emulation
Why not go the other way arround? CDI managed beans provide more flexibility and can do everything your JSF ManagedBeans can. See #4347874Howard
@Howard I'm switching from managedbean to named. Any chance you know if I have to change EJB to Inject and ManagedProperty to Inject aswell ? Thanks in advance.Gaudet
@Gaudet You don't have to switch @EJB for @Inject but @ManagedProperty should only be used from JSF managed beans and therefore not used in pure CDI context, so replace them with @Inject.Howard

© 2022 - 2024 — McMap. All rights reserved.