1

I have the following UserView class:

@ManagedBean(name="usersView", eager=true)
@ApplicationScoped
public class UserView
{
    ...

    public void setUsers(...)
    {
        ...
    }
}

I then have another class, UserService which tries to access this bean and then call this method, as follows:

UserView usersView = (UserView) FacesContext.getCurrentInstance().getExternalContext().getSessionMap("usersView");

usersView.setUsers(...)

My issue is, is that usersView keeps coming back as null and hence the method cannot be called.

My end goal is to use this data in a PrimeFaces datatable, like so:

<p:dataTable var="user" value="#{usersView.users}" ...>

I have also tried changing the scope to SessionScoped, but it is still null and I cannot figure out why.

Any suggestions would be greatly appreciated.

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
James
  • 1,345
  • 2
  • 19
  • 45
  • Why are you trying to get an application scoped bean from the session map instead of the application map? – BalusC Jun 22 '16 at 10:31
  • I previously had it as a session scoped bean, so forgot to change it. Nonetheless, it still didn't work from the session map when it was indeed session scoped. – James Jun 22 '16 at 10:32
  • As per the [javadoc](https://docs.oracle.com/javaee/7/api/javax/faces/bean/ManagedBean.html), `eager` has only effect on application scoped beans. – BalusC Jun 22 '16 at 10:33
  • When it was a session scoped bean, I removed the eager as above and it still didn't work. I've now switched it to getApplicationMap() and it's worked fine. Could you explain why it was null as a session scoped bean but now its not as an application scoped bean if that makes sense? Thanks for your help. – James Jun 22 '16 at 10:35

1 Answers1

1

The getExternalContext().getXxxMap().get("beanName") approach won't autocreate beans if they don't exist yet. Managed beans will only be autocreated when an EL expression referencing the bean is evaluated. Accessing the scope map doesn't do that. For that, use @ManagedProperty in the source bean instead. You can specify an EL expression in its value.

@ManagedProperty("#{userView}")
private UserView userView; // +setter (no getter required).

Note that this only works if the source bean has the same or a narrower scope than the target bean. If that's not the case, consider managing beans using CDI instead of JSF. You can then use @Inject instead of @ManagedProperty (which doesn't require a setter by the way). Moreover, @ManagedBean and friends is deprecated in upcoming JSF 2.3.

As to eager=true, this has only effect on @ApplicationScoped beans. See also the javadoc (emphasis mine).

...

If the value of the eager() attribute is true, and the managed-bean-scope value is "application", the runtime must instantiate this class when the application starts. This instantiation and storing of the instance must happen before any requests are serviced. If eager is unspecified or false, or the managed-bean-scope is something other than "application", the default "lazy" instantiation and scoped storage of the managed bean happens.

...

See also:

Community
  • 1
  • 1
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452