2

ello

I have 2 Managed beans, one View scoped, the other Session scoped. The View scoped bean is defined as

@ManagedBean
@ViewScoped
public class InvoiceController implements Serializable {
  private static final long serialVersionUID = 1L;

  @ManagedProperty(value="#{invoiceService}")
  private InvoiceService invoiceService;

The session scoped bean as

@ManagedBean
@SessionScoped
public class InvoiceService implements Serializable{

I am using the session scoped bean to hold a flag used to decide if a panel should be rendered, when I run this through the debug I find that every time I call the method on the sesison bean, it is a new instance of the bean and therefore does not retain the value of my flag between requests.

What am I doing wrong?

MGB
  • 31
  • 1
  • 6

2 Answers2

9

That can happen if you have imported @SessionScoped from the javax.enterprise.context package instead of from the javax.faces.bean package. The former works on CDI @Named beans only, while the latter works on JSF @ManagedBean beans only.

A JSF @ManagedBean without any valid scope would default to @NoneScoped which means that it's newly constructed on every single EL expression referencing the bean, such as the @ManagedProperty. This explains the symptoms you're seeing.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks BalusC, I have checked the import and it is javax.faces.bean package. – MGB Aug 09 '12 at 20:18
  • Then you've a bigger problem. Is your view scoped bean also recreated or maintained? Are you using server or client side state saving? Is the session cookie properly maintained across subsequent requests? – BalusC Aug 09 '12 at 20:23
  • Wow, and this is when I'm trying to do the simple bits. I will check - thanks – MGB Aug 09 '12 at 21:13
0

I had a similar problem. I use a save-method in the view scoped bean that calls a method in the session scoped bean to update some values.

This is what I found out by debugging (excuse my non-Java-guru English):

When first loading the page, the instance number of the injected session bean was for example 111111. But in the save-method (and all other methods called by an action like a commandButton or action listeners btw), suddenly the session bean was of another instance (say 222222).

Both instances 111111 and 222222 contained the very same values. All methods I called now were done in the 222222 instance and it changed values in there as I wanted it. But the 111111 instance remained untouched and unchanged.

So 222222 was basically a deep(?) clone of 111111, and not even a copy.

But, after the save-method was done and the page got reloaded, the original 111111 instance was used again in the view scope bean. The 222222 instance just got thrown to the garbage.

My solution for this problem:

I'm not using the ManagedProperty injection anymore.

Instead I made some helper code to get the session bean wherever I need it (aka in the view scoped bean methods):

public Object getSessionBean(String sessionBeanName)
    {
        return FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(FacesContext.getCurrentInstance().getELContext(), null, sessionBeanName);
    }

For your example above, the call would be:

InvoiceService invoiceService = (InvoiceService) helper.getSessionBean("invoiceService");

Call it in your methods, do not store it as a field in the view scoped bean.

I hope this somehow helps you fix your problem.