9 Replies Latest reply: Sep 4, 2012 10:13 PM by EJP RSS

    @EdBurns - ManagedProperty query

    EJP
      Apologies in advance for the probable triviality of this question. I have
      @ManagedBean(name = "vsim")
      @ViewScoped
      public class VSIMBean implements Serializable
      {
         // ...
        @ManagedProperty(value="vSIMSystem")
         private VSIMSystem vSIMSystem.
      // ...
      }
      
      @ManagedBean()
      @ApplicationScoped()    // stateless
      public class VSIMSystem implements Serializable
      {
      ...
      }
      in conjunction with STATE_SAVING_METHOD=client. This means that vSIMSystem gets serialized to and from the client on every request in the view scope of VSIMBean. However it occured to me that as vSIMSystem is application-scoped this is pointless and that I could save some bandwidth by making it transient ini the VSIMBean, assuming/hoping that the @ManagedProperty annotation would cause it to be re-injected when VSIMBean got read back from the client. But it doesn't, so I get NPEs instead.

      Now this seems odd to me. First, it means that I have to serialize an application-scoped bean along with a view-scoped bean, which I find intrinsically odd. Second, it means that on deserialization I now have two copies of an application-scoped bean, which seems even odder, and somewhat contrary to my expressed intentions ;-) Third, it means that the state saving mechanism doesn't perform re-injection after deserialization, which also seems like a bit of a gap.

      Am I missing something very basic? i.e. is there a way to get the effect I want?

      Edit: I came to the conclusion that the secondary beans here should really be @NoneScoped, and that as they are stateless the serialization cost is minimal. Still seems a bit strange to me.

      Another thing that seems strange is that @ManagedProperty needs a setter but @Resource doesn't. I know they come from different specifications, but ...

      Edited by: ejp on 28/08/2010 13:39
        • 1. Re: @EdBurns - ManagedProperty query
          956404
          I just ran into this myself and developed a ViewScopePhaseListener that will re-inject @ManagedProperty values on @ViewScoped managed-beans during a postback. For more info, see: http://issues.liferay.com/browse/FACES-1400
          • 2. Re: @EdBurns - ManagedProperty query
            EJP
            Your blog says that Mojarra does perform the injection. My post above says it doesn't. How is this the same issue?
            • 3. Re: @EdBurns - ManagedProperty query
              gimbal2
              Surely this has been fixed in core JSF by now, right?
              • 4. Re: @EdBurns - ManagedProperty query
                EJP
                There have been several problems with @ViewScoped which are only now being addressed. Previously the attitude seemed to be that they couldn't be fixed.
                • 5. Re: @EdBurns - ManagedProperty query
                  gimbal2
                  Still! Well I've been avoiding using ViewScoped because of those issues in the past and I must say: I don't miss it. Since I've adopted a comfortable way of working without needing ViewScoped at all, I doubt I'll ever use it for anything.
                  • 6. Re: @EdBurns - ManagedProperty query
                    Edburns-Oracle
                    For what it's worth, I just made a commit regarding @ViewScoped for JSF
                    2.2. [1]. The @javax.faces.bean.ViewScoped will eventually, though not
                    in JSF 2.2, be deprecated. Instead, use the new
                    @javax.faces.flow.ViewScoped annotation.

                    First, I had to correct an apparent error in your scenario.

                    When you say

                    @ManagedProperty(value="vSIMSystem")
                    private VSIMSystem vSIMSystem;

                    you are saying that you want the string "vSIMSystem" injected into the
                    setter for field vSIMSystem. This is from the javadoc for
                    javax.faces.bean.ManagedPropercty.

                    The value of the value() attribute may be a literal String or a
                    ValueExpression. If the latter, the expression must not be evaluated
                    until the bean is instantiated.

                    However, the type of that setter is, of course VSIMSystem. If I give
                    the VSIMSystem a name of vSIMSystem, and change the @ManagedProperty
                    value to be #{vSIMSystem}, the beans get arranged correctly.

                    Now, on to your assertion that the re-injection does not occur.

                    I marked the vSIMSystem ivar as transient. When I reload the page, I
                    observe that the setter is called each time, though the constructor is
                    only called if is the first time for this session that this view is
                    being hit.

                    What version of Mojarra are you trying this on? In my case, I'm using
                    the trunk, but it's possible an older version does indeed have a
                    problem.

                    I have uploaded the test app from which I draw my conclusions here [2].

                    Ed

                    [1] http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1087

                    [2] http://java.net/projects/javaserverfaces/downloads/download/scratch/viewScopedExport.zip
                    • 7. Re: @EdBurns - ManagedProperty query
                      EJP
                      Ed, thanks for the followup. I did have #{vSimSystem} in the code, just a typo here. The only changes I ultimately made were to remove 'transient' and to make VSIMSystem @ViewScoped as well, for another reason. It would have been JSF 1.x at the time. I'm now on 2.1.11 so I will try again with 'transient'.

                      Meanwhile do you have any comment on why '@ManagedProperty needs a setter but @Resource doesn't'?
                      • 8. Re: @EdBurns - ManagedProperty query
                        Edburns-Oracle
                        EJP> Meanwhile do you have any comment on why '@ManagedProperty needs a setter but @Resource doesn't'?

                        That is a straight up inconsistency. Are you able to move forward to CDI? I'll note that in JSF 2.2, I added this text [1] to the
                        "Faces Managed Bean Annotation Specification for Containers Conforming to Servlet 2.5 and Beyond":

                        The annotations in this package may be deprecated in a future version of this specification because they duplicate
                        functionality provided by other specifications included in JavaEE. When possible, the corresponding annotations from
                        the appropriate Java EE specification should be used in preference to these annotations.

                        The new @javax.faces.flow.ViewScoped annotation is just such an example.

                        Ed

                        [1] https://maven.java.net/service/local/repositories/snapshots/archive/javax/faces/javax.faces-api/2.2-SNAPSHOT/javax.faces-api-2.2-20120821.085555-51-javadoc.jar/!/managed-bean-javadocs/index.html
                        • 9. Re: @EdBurns - ManagedProperty query
                          EJP
                          Now, on to your assertion that the re-injection does not occur.

                          I marked the vSIMSystem ivar as transient. When I reload the page, I
                          observe that the setter is called each time, though the constructor is
                          only called if is the first time for this session that this view is
                          being hit.
                          Ed

                          I am still seeing this with Mojarra 2.1.11. It happens after I submit an action to the page. The @ViewScoped VSIMBean gets serialized to the browser, comes back with the POST data, the setVSIMSQL() setter is not called, the VSIMSQL member is null, I get NPEs. The submit is done via an "actionListener=" attribute on a <a4j:commandButton>, if that makes any difference (RichFaces 3.3.3 and therefore Facelets 1.1.15).

                          EJP