8 Replies Latest reply on Aug 9, 2010 8:35 AM by Shervin Asgari

    Validation in an optional object

    Michael Paffhausen Newbie

      Seam 2.2.0.GA


      Hi all,


      I am new to Seam, so sorry if this is a no-brainer...


      I want to write a class Person, which contains an Address object. The address is supposed to be optional, but if it is given, it must be correct.


      Address.java looks something like this:


      @Entity
      @Name("address")
      public class Address implements Serializable {
      
          private static final long serialVersionUID = 2589228577037539089L;
      
          @Id
          @GeneratedValue
          private Long addressId;
          
          @NotNull
          @Length(max = 128)
          private String street;
          
          @NotNull
          @Range(min = 10000, max = 99999)
          private Integer postCode;
          
      ...
      
      }
      



      And my Person.java:


      @Entity
      @Name("person")
      public class Person implements Serializable {
      
          private static final long serialVersionUID = 2836445289101515299L;
      
          @Id
          @GeneratedValue
          private Long personId;
      
      ...
      
          @OneToOne(optional = true, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
          @JoinColumn(name = "addressId")
          private Address address;
      
      ...
      
          public Person() {
              this.address = new Address();
          }
          
      ...
      
      }
      



      My form uses the Hibernate annotations for validation. And here comes the crux: If the user enters a valid address, everything is fine. If he, however, tries to skip entering the address -- which is supposed to be optional, after all -- the validators of the Address class complain.


      What is the correct approach to implementing this? Thanks for any suggestions!

        • 1. Re: Validation in an optional object
          Shervin Asgari Master

          The code looks correct except the Person() constructor.
          This is not how you should initialize an Address. In this example, address is never null. Just remove the entire constructor and it should be fine.


          Another thing you should avoid doing is putting your Entity beans as seam components. You should seperate them. Let Entity beans be entity beans, and instead create a PersonAction class where this is a seam component instead and performs the saving and stuff.

          • 2. Re: Validation in an optional object
            Michael Paffhausen Newbie

            Thanks a lot for your answer, Shervin.


            Unfortunately, when I remove the constructor as you suggested, I get a PropertyNotFoundException


            (Caused by javax.servlet.ServletException with message: "/person.xhtml @39,77 value="#{personHome.instance.address.street}": Target Unreachable, 'address' returned null on 'de.mpa.z1.entity.Person')
            



            when I try to save some user input. Which is why I added the constructor in the first place... The relevant part of person.xhtml looks like this:


            <s:decorate id="streetField" template="layout/edit.xhtml">
              <ui:define name="label">street</ui:define>
              <h:inputText id="street" value="#{personHome.instance.address.street}"/>
            </s:decorate>
            



            PersonHome.java (as generated by seam-gen):


            @Name("personHome")
            public class PersonHome extends EntityHome<Person> {
            ...
            }
            


            Is there maybe something wrong with my EL expression?


            Regarding your suggestions on best practices: I am definitely going to keep that in mind. Currently, however, I am still in an early learning phase -- actually, I am still just experimenting with the code generated by seam-gen -- so I would like to get this simple approach to work first.

            • 3. Re: Validation in an optional object
              Shervin Asgari Master

              In my opinion, I think learning Seam from seam-gen is not an easy task. It is easier to try to do stuff manually and avoid using the Seam Entity Framework.
              That said, lets see if I can help you out.



              Your first error Target Unreachable, 'address' returned null
              indicates that the address object is null, thus it cannot perform your next task which is getting the address. You should first do a check to see if the address is null or not before calling the code.


              You can do that in several ways. I like doing these kind of tests on a <s:fragment>




              <s:fragment rendered="#{not null personHome.instance.address}">
                Address object is not null, and the value of street is: 
                <h:outputText value="#{personHome.instance.address.street}"/>
              </s:fragment>



              • 4. Re: Validation in an optional object
                Shervin Asgari Master

                I meant to say:


                Your first error Target Unreachable, 'address' returned null indicates that the address object is null, thus it cannot perform your next task which is getting the street.

                • 5. Re: Validation in an optional object
                  Michael Paffhausen Newbie

                  I already did check the address object in the past, and it was indeed null. Which is why I added the constructor with "address = new Address()"...


                  The core of my problem seems to be that I do not understand who should create the address object, and when? I would have expected / hoped, that it would have been automagically created by the framework -- just as, for example, the String objects in Person...

                  • 6. Re: Validation in an optional object
                    Shervin Asgari Master

                    Yes I see your problem.


                    I think what you should do is check out some of the seam examples (there are lots of them). Just check the example folder in seam. You will see a lot of working useful projects that can better make you understand how things work.

                    • 7. Re: Validation in an optional object
                      Michael Paffhausen Newbie

                      I did that before posting, believe me! ;o) Unfortunately, I did not find anything that seemed to match my current problem (i.e. validation of composite objects that might or might not be null).


                      Anyway, thanks a lot for your input!

                      • 8. Re: Validation in an optional object
                        Shervin Asgari Master

                        Its really not that difficult.


                        Here is some pseudo code on how you can do it.


                        - User pushes a button to add address to user
                        - When user pushes this button you do a new Address(); and then present the user with the option to set the address.
                        Otherwize, its just null.