I\'m trying to inject the value of one sessionscoped bean into a viewscoped bean but it keeps returning null, here\'s a snippet:
import javax.faces.applicati
Recently I have problem with injecting nested managed bean properties by @ManagedProperties
too. Once injected it never changed. I did a workaround by evaluating EL in getter instead of injecting it.
Try that:
public String getUserName() {
FacesContext context = FacesContext.getCurrentInstance();
return (String) context.getApplication().evaluateExpressionGet(context,"#{user.userName}", String.class);
}
You can also try injecting entire user
bean and get userName
field from it in getter.
I had this problem, and the problem was actually twofold. (Note also that @ManagedProperty will only ever work in a @ManagedBean class and if that @ManagedProperty class is of the same or lesser scope (application, session, view, request, etc.).) Here is how I fixed it:
Problem 1: JSF is stupid and doesn't handle @ManagedProperty
injection properly in abstract
classes.
Solution:
@ManagedProperty
be annotated with @ManagedBean
.abstract
class that uses the property not be annotated with @ManagedProperty
and instead only provide abstract getter and setter methods that non-abstract classes will each override.abstract
class's getter method instead of the @ManagedProperty itself in abstract
classes.Problem 2: JSF is stupid and doesn't handle @ManagedProperty
injection properly in @ManagedBean classes not created by JSF (i.e. you are creating these classes yourself using new
).
Solution options:
@ManagedProperty
.MyClass example = Utils.getELValue("EL Expression Goes Here", MyClass.class);
public static <T> T getELValue(final String elName, final Class<T> clazz) {
FacesContext fc = FacesContext.getCurrentInstance();
return (T) fc.getApplication().getELResolver().getValue(fc.getELContext(), null, elName);
// Potential (untested) alternative:
// ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getSession().getAttribute("")
}
#{user.userName}
is interpreted by JSF as getUser().getUserName()
So it is better to have a @ManagedProperty
of type User
, with its getter/setter methods getUser
/setUser
. With that you can access the user's name by #{user.userName}
.
With all setters/getters in place, I was having the same problem (null reference to user) because of missing empty constructor in User class.
In the example you provided, the dataBrowser
and user beans are instantiated before constructing the table, so referencing #{dataBrowser.userName}
should already find the userName @ManagedProperty
correctly injected (not being a @PostConstruct
problem).
I just came across the same problem, and found out by chance, that it is not working, if I try with firefox (actually icedove under linux), but well working, if I try with the eclipse build-in browser.
Even so this does not make sense to me, have you tried with different browsers already?
michal777's answer is very well working. I have extended it to this:
@ManagedProperty("#{nameBean}")
private NameBean nameBean;
public NameBean getNameBean() { return nameBean; }
public void setNameBean(NameBean nameBean) { this.nameBean = nameBean; }
public NameBean getNameBean_Workaround() {
FacesContext context = FacesContext.getCurrentInstance();
return (NameBean) context.getApplication().evaluateExpressionGet(context,"#{nameBean}", NameBean.class);
}
and later on:
if (nameBean != null) {
nameBean.setName("achsooo");
}
else {
getNameBean_Workaround().setName("achsooo2222");
}
Now, in the eclipse browser "achsooo" gets set, and in icedove "achsooo2222" gets set.