9 Replies Latest reply on Oct 1, 2007 6:57 PM by smithbstl

    Entity Injection question

      Lets say I have an input field in a page

      <h:inputText value="#{someEntity.someProperty}"/>
      <h:commandButton actionListener="#{foo.submit}"/>
      


      @Stateful
      @Name("foo")
      public class foo {
      
      @In(required=false)
      SomeEntity someEntity;
      
      @Logger
      Log log;
      
      public void submit() {
      if (someEntity != null) {
       log.debug("Entity IS NOT NULL");
      else {
       log.debug("Entity IS NULL");
      }
      }
      


      Since I am referencing a property of someEntity in my page, the entity is automatically instantiated using its no arg constructor, even though I have not specified @In(create=true), correct? There is never a case where someEntity will be null.

      I have a page where I have a number of these types of inputs that are optional. Even if I do not enter anything in the input component and its the only component that refers to a particular entity, I still get non null values when the entity is submitted. All of the properties of the entity are null but the object itself has been created by Seam.

      I end up having to do this instead

      public void submit() {
      if (someEntity.someProperty != null) {
       log.debug("Entity's Property IS NOT NULL");
      else {
       log.debug("Entity's Property IS NULL");
      }
      }


      I understand this behavior but it just seems a little counter intuitive to someone trying to learn the basics of bijection.

      I am just making sure I understand it. So am I going to have to check properties like this to clarify if an object is "functionally null" (all properties are null)?

        • 1. Re: Entity Injection question

          In the scenario you describe, the only time an entity is going to be automatically created is if it is a named Seam component and it has the annotation @AutoCreate. Is this how your entity is annotated?

          ...
          @Entity
          @Name("someEntity")
          @AutoCreate
          public class SomeEntity {
          ...


          Otherwise you would have to have a factory method somewhere...

          @Factory(value="someEntity")
          public SomeEntity initSomeEntity() {
           return new SomeEntity();
          }


          You have to specify when Seam should create instances of components.

          As far as the following code...
          public void submit() {
          if (someEntity.someProperty != null) {
           log.debug("Entity's Property IS NOT NULL");
          else {
           log.debug("Entity's Property IS NULL");
          }
          }


          This code is necessary depending on what you're doing. If you performing validation this could actually be done through <s:validate> or <s:validateAll> and use of @NotNull on your entity attribute. Hope that helps.

          • 2. Re: Entity Injection question

            None of my entities are tagged with @AutoCreate but if I refer to a property of the entity in a jsf page, the entity is created with a no-arg constructor or me.

            To me this behavior actually makes sense because when the page is loaded all the el is evaluated and beans are created when referenced from el.

            • 3. Re: Entity Injection question
              stephen.friedrich

              Jacob, I think you are wrong.

              If you reference a seam component in EL in the component instance will _always_ be created if it was null.

              "smithbstl": You have to do it the way you did, if you really need to check for
              null properties. How comes, that you must do so?

              • 4. Re: Entity Injection question

                 

                "stephen.friedrich" wrote:
                If you reference a seam component in EL in the component instance will _always_ be created if it was null.


                That's interesting. Is that documented or have you simply experimented and discovered this? It certainly doesn't work that way for @In.

                • 5. Re: Entity Injection question
                  stephen.friedrich

                  I can't really point to a paragraph in the reference where it's explicitly described.

                  Yet, every example uses components that way: Usually the very first reference to a component is encountered in EL in html/jsp.

                  When explaining the registration example the 1.2.1 reference says:

                  1.2.2. How it works
                  When the form is submitted, JSF asks Seam to resolve the variable named user. Since there is no value already bound to that name (in any Seam context), Seam instantiates the user component, and returns the resulting User entity bean instance to JSF after storing it in the Seam session context.


                  (Well, actually I think that's wrong, too. The EL is evaluated first when the form is rendered, so the component gets instantiated even before submit.)

                  • 6. Re: Entity Injection question

                    LOL, apparently I'm having an off day... after looking at my code I am doing this in several places. I guess I need another cup of coffee :-)

                    In addition, after looking back, I misread this portion of your post smithbstl...

                    "smithbstl" wrote:
                    I have a page where I have a number of these types of inputs that are optional. Even if I do not enter anything in the input component and its the only component that refers to a particular entity, I still get non null values when the entity is submitted. All of the properties of the entity are null but the object itself has been created by Seam.


                    Obviously if these inputs are optional you would not want to validate that they are not null so disregard my post about @NotNull and s:validate. Stephen is right on both counts. Sorry guys, not my day.

                    • 7. Re: Entity Injection question

                      Right s:validate works to circumvent the problem in my trivial example. I have more problems when trying to evaluate objects usually in EL when choosing to render them or not.

                      I end up having to check the value of the primary key of the entity instead of the entity itself. For example, if had some dependent controls and did not want to render the other controls until previous ones where filled in.

                      <h:inputText value="#{foo.bar}">
                       <a4j:support event="onblur" actionListener="#{backing.submitFoo}"/>
                      </h:inputText>
                      <h:inputText value="#{goo.bar}"
                      rendered="#{foo.Id == null}"/>


                      It would be more intuitive to just say
                      rendered="#{foo == null}"

                      I understand why I can't but its misleading to a newcomer



                      • 8. Re: Entity Injection question
                        pmuir

                        Right, you might want to add something to the SeamProblemsFAQ on this :)

                        • 9. Re: Entity Injection question

                          Done