12 Replies Latest reply: May 3, 2012 8:10 AM by Brendan Healey RSS

Inconsistent ApplicationScoped bean value

Jean-Noel Colin Newbie

Hello,

 

Here's my problem.

 

I have defined an ApplicationScoped managed bean, which contains some Lists of values

@ManagedBean

@ApplicationScoped

public class GlobalData implements Serializable {

 

I have two other beans, defined as:

 

@ManagedBean

@ViewScoped

public class AdminEventsBean implements Serializable {

  @ManagedProperty(value = "#{globalData}")

          private GlobalData globalData = null;

 

and

 

@ManagedBean

@ViewScoped

public class RegistrationBean implements Serializable {

  @ManagedProperty(value = "#{globalData}")

          private GlobalData globalData = null;

 

When I call a reload method from the first one on the ApplicationScoped one, I can see that the list gets reloaded properly.

However, when I access the list from the second on on the ApplicationScoped one, I can't see the updated list, it always contains the first set of values.

 

Did I miss something or is there something wrong?

 

Thanks for your help

 

Jean-Noël

  • 1. Re: Inconsistent ApplicationScoped bean value
    Brendan Healey Master

    Looks ok except for initialising globalData to null in the view scoped beans, can you try without this? Also

    check that you have the correct javax.faces.bean... imports for the @...Scoped annotations and not CDI

    variants.

     

    Regards,

    Brendan.

  • 2. Re: Inconsistent ApplicationScoped bean value
    Jean-Noel Colin Newbie

    I just try without setting globalData to null, and the problem is still the same.

     

    Something to add though (not related to the test you asked for):

     

    If, in the setter for globalData defined in RegistrationBean, I add a call to the reload function:

     

              public void setGlobalData(GlobalData globalData) {

                        this.globalData = globalData;

                        globalData.reloadEvents();

              }

     

    then I get the proper list.

     

    So it's really like if both ViewScoped bean had their own version of the ApplicationScoped bean, which seems against the design, doesn't it? :-)

  • 3. Re: Inconsistent ApplicationScoped bean value
    Brendan Healey Master

    That's got to be what's happening, 2 app scoped beans !! Can you put some logging in a no-arg constructor and an

    @PostConstruct method and print out this.toString() - also in the getGlobalData() method.

  • 4. Re: Inconsistent ApplicationScoped bean value
    Jean-Noel Colin Newbie

    I hope I understood your suggestion correctly.

     

    In each of the 3 beans, i added the following method:

      @PostConstruct

              public void postConstructMethod() {

                        System.out

                                            .println("RegistrationBean PostConstruct: " + globalData.toString());

              }

     

    (of course, in globalData, it outputs this.toString())

     

    When looking at the logs, here's what i get:

     

    ws-92-166:logs jnc$ grep PostConstruct catalina.out

    GlobalData PostConstruct: be.erigo.fclusers.GlobalData@2af7b740

    RegistrationBean PostConstruct: be.erigo.fclusers.GlobalData@2af7b740

    AdminEventsBean PostConstruct: be.erigo.fclusers.GlobalData@2af7b740

    RegistrationBean PostConstruct: be.erigo.fclusers.GlobalData@2af7b740

     

    so it looks consistent, doesn't it?

     

    I've also added a printout in each constructor, and here again, output seems ok:

     

    ws-92-166:logs jnc$ grep Building catalina.out

    Building RegistrationBean

    Building GlobalData

    Building AdminEventsBean

    Building RegistrationBean

     

    But still, the lists are not consistent in the two ViewScoped beans, even though I can see the reload taking place in the ApplicationScoped bean.

     

    Thanks for your help

  • 5. Re: Inconsistent ApplicationScoped bean value
    Brendan Healey Master

    what is globalData.toString() when you access the data in the view scoped beans? if the data is different, it has to

    be a different hash code, unless the data is being changed between accesses. There is an outstanding issue related

    to this:

     

    http://java.net/jira/browse/JAVASERVERFACES-1705

     

    What JSF version are you using? A real long shot but perhaps try @ManagedBean(eager = true) on the app scoped

    bean, no real reason but can't think of anything else!

  • 6. Re: Inconsistent ApplicationScoped bean value
    Jean-Noel Colin Newbie

    Hello again,

     

    To be a bit more concrete: the AdminEventsBean allows to create new data and push it to the database (using hibernate); to avoid going to the DB to query the data, since it's rather static, it also calls a reload function on the GlobalData bean, that reloads the data from the db; then, the RegistrationBean calls the getEventItems, which is defined as:

              private List<SelectItem> eventItems = new ArrayList<SelectItem>();

     

    and accessible through getter only.

     

     

    I tried adding more printouts, and I get surprising results. In the ApplicationScoped bean (GlobalData), in the getter for the inconsistent field, I've added a print of the content of the list:

     

     

              public List<SelectItem> getEventItems() {

     

                        System.out

                                            .println("GlobalData.getEventItems: " + this.toString() + "#" + eventItems.toString());

      return eventItems;

              }

     

    When I check the logs, I find the following:

     

    ws-92-166:logs jnc$ grep GlobalData.getEventItems catalina.out
    GlobalData.getEventItems: be.erigo.fclusers.GlobalData@3addc3fe#[javax.faces.model.SelectItem@356e76e3, javax.faces.model.SelectItem@673f4c7c, javax.faces.model.SelectItem@6cb695d8, javax.faces.model.SelectItem@4727cfaa, javax.faces.model.SelectItem@6b2c665]
    GlobalData.getEventItems: be.erigo.fclusers.GlobalData@3addc3fe#[javax.faces.model.SelectItem@356e76e3, javax.faces.model.SelectItem@673f4c7c, javax.2.1.7faces.model.SelectItem@6cb695d8, javax.faces.model.SelectItem@4727cfaa, javax.faces.model.SelectItem@6b2c665]
    GlobalData.getEventItems: be.erigo.fclusers.GlobalData@4ffecba5#[javax.faces.model.SelectItem@60ebe6aa, javax.faces.model.SelectItem@1f74d49c, javax.faces.model.SelectItem@2f325de6, javax.faces.model.SelectItem@13b2bf3f, javax.faces.model.SelectItem@3c29cb33, javax.faces.model.SelectItem@5bdba020]
    GlobalData.getEventItems: be.erigo.fclusers.GlobalData@3addc3fe#[javax.faces.model.SelectItem@356e76e3, javax.faces.model.SelectItem@673f4c7c, javax.faces.model.SelectItem@6cb695d8, javax.faces.model.SelectItem@4727cfaa, javax.faces.model.SelectItem@6b2c665]
    GlobalData.getEventItems: be.erigo.fclusers.GlobalData@3addc3fe#[javax.faces.model.SelectItem@356e76e3, javax.faces.model.SelectItem@673f4c7c, javax.faces.model.SelectItem@6cb695d8, javax.faces.model.SelectItem@4727cfaa, javax.faces.model.SelectItem@6b2c665]
    GlobalData.getEventItems: be.erigo.fclusers.GlobalData@3addc3fe#[javax.faces.model.SelectItem@356e76e3, javax.faces.model.SelectItem@673f4c7c, javax.faces.model.SelectItem@6cb695d8, javax.faces.model.SelectItem@4727cfaa, javax.faces.model.SelectItem@6b2c665]

     

     

    All lists are the same, except the 3d one, which is the one obtained after calling the reload function on globalData from one of the ViewScoped beans. So it shows that after the call to reload, the list is properly updated (it contains the additional element), but as soon as I move to another page which calls the getEventItems (through the JSF lifecycle), it returns to the old version.

     

    I'm using JSF 2.1.7

     

    I tried the eager=true option but it didn't help

     

    Thanks for your help

  • 7. Re: Inconsistent ApplicationScoped bean value
    Brendan Healey Master

    >GlobalData@4ffecba5

     

    this is the problem, in the third list globalData is a seperate chunk of VM entirely. There's just got to be

    something different about the environment this is running in, and how it accesses globalData, compared

    to when you have GlobalData@3addc3fe.


  • 8. Re: Inconsistent ApplicationScoped bean value
    Jean-Noel Colin Newbie

    I do understand that that's the problem, but what can cause this? The constructor of GlobalData is called only once, I verified this. So how can I have two instances of an ApplicationScoped bean?

     

    I made another test: in the AdminEventsBean, which calls the reload function on GLobalData, here's the trace:

     

    Building AdminEventsBean

    AdminEventsBean Setting globalData to be.erigo.fclusers.GlobalData@13603408

    AdminEventsBean PostConstruct: be.erigo.fclusers.GlobalData@13603408

    AdminEventsBean Reloading be.erigo.fclusers.GlobalData@6c910628

    AdminEventsBean Reloaded 5

     

    the first message comes from the constructor

    the second one comes from the setter of the managed-property. Is it normal that it comes before the PostConstruct?

    the third one is from the PostConstruct

    the fourth one is called from the Action method, described in the xhtml as:

      <h:commandButton action="#{adminEventsBean.addAction}" value="Add"

      rendered="#{!adminEventsBean.updateMode}" />

     

    it clearly references a different instance of GlobalData, which has never been instantiated (at least if I trust the printout added to the constructor)

     

    So what's happening here?

     

    Thanks a lot


  • 9. Re: Inconsistent ApplicationScoped bean value
    Brendan Healey Master

    Hang on, I may have got it. Just remembered from "Core JSF" that the @ManagedProperty must have a public

    setter method, so does the bean that generated this output (AdminEventsBean Reloading be.erigo.fclusers.GlobalData@6c910628)

    have a setGlobalData() method?

     

    Regards,

    Brendan.

  • 10. Re: Inconsistent ApplicationScoped bean value
    Jean-Noel Colin Newbie

    Unfortunately, yes, all beans have public setters and getters for the @ManagedProperty.

    I did another test, and found something else which is very strange: in the addAction action which is used from the AdminEventsBean (viewscoped) to store new items in the DB and then invoke the reload function on globalData, I added the following printouts:

     

                        System.out

                                            .println("AdminEventsBean addAction " + globalData.toString());

                        FacesContext context = FacesContext.getCurrentInstance();

                        GlobalData bean = (GlobalData) context.getApplication().evaluateExpressionGet(context, "#{globalData}", GlobalData.class);

                        System.out

                        .println("AdminEventsBean addAction bis " + bean.toString());

     

     

    Looking at the trace, I can see that the two globalData are not the same; the first one (GlobalData@38493622) is incorrect, and it's the one that will be used to reload, hence my problem. The same applies to the other viewscoped bean

     

    Building AdminEventsBean

    AdminEventsBean Setting globalData to be.erigo.fclusers.GlobalData@3303dccc

    AdminEventsBean PostConstruct: be.erigo.fclusers.GlobalData@3303dccc

    AdminEventsBean addAction be.erigo.fclusers.GlobalData@38493622

    AdminEventsBean addAction bis be.erigo.fclusers.GlobalData@3303dccc

    AdminEventsBean Reloading be.erigo.fclusers.GlobalData@38493622

    AdminEventsBean Reloaded 6

     

    again, many thanks for your help

  • 11. Re: Inconsistent ApplicationScoped bean value
    Jean-Noel Colin Newbie

    Brendan, I found it!!

     

    In my web.xml, I had:

     

      <context-param>

                        <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>

                        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>

      <param-value>client</param-value>

      </context-param>

     

    Changing it to:

     

      <context-param>

                        <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>

                        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>

      <param-value>server</param-value>

      </context-param>

     

    did the trick. Not sure why, though...

     

    Thanks a lot for your help


  • 12. Re: Inconsistent ApplicationScoped bean value
    Brendan Healey Master

    Great you got it fixed, I've added this to my list of "things to watch out for".