7 Replies Latest reply on Sep 23, 2010 12:13 PM by lvdberg

    Polymorphism and properties

    beligum.b.beligum.org

      Hi all,


      I'm facing an issue in Seam 2 (Jboss 4):


      I've got a class Person:




      @Entity 
      @Name("person")
      @Table(name="person")
      @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
      @DiscriminatorColumn(
                           name="type",
                           discriminatorType=DiscriminatorType.STRING
      )
      @DiscriminatorValue("person")
      @Indexed
      public class Person implements Serializable
      {
      ...
      }



      and a subsclass Student:




      @Entity
      @Name("student")
      @DiscriminatorValue("student")
      @Indexed
      public class Student extends Person
      {
      ...
      }




      I'm outjecting a Person/Student as follows in an Event-scoped action bean:




      @Stateful
      @Scope(ScopeType.EVENT)
      @Name("pageManager")
      public class PageManager
      {
      @Out(required=false)
      private Person selectedProfile;
      
      @Factory("selectedProfile")
          public void initSelectedProfile()
          {
           if (this.selectedProfileId!=null) {
               try {
                this.selectedProfile = (Person)this.entityManager.createQuery("SELECT DISTINCT p FROM Person p WHERE p.id=:profileId ")
                .setParameter("profileId", this.selectedProfileId)
                .getSingleResult();
                
                this.selectedProfile = this.selectedProfile;
               }
               catch (Exception e) {}
           }
          }
      }




      Now my problem: if I try to access a property of the Student-class in some JSF code, eg


      #{selectedProfile.dormAddress}



      I get an exception:




      javax.faces.FacesException: javax.el.PropertyNotFoundException: value="#{selectedProfile.dormAddress}": Property 'dormAddress' not found on type Person_$$_javassist_497




      Oddly enough, when I debug the query-code, I'm finding a Javassist class holding a good Student object with the right properties filled in.


      Any thoughts?


      b.

        • 1. Re: Polymorphism and properties
          lvdberg

          Hi,


          Try using a get Method for selectedProfile and see if the standard way works.



          #{pageManager.selectedProfile.dormAddress}



          The Hibernate JavaAssist (the Query)  is not the same as the JSF-one.The JSF error states that it has a Person and Not a Student.


          Leo


          • 2. Re: Polymorphism and properties
            beligum.b.beligum.org

            Hmm, no doesn't seem to work..


            This is the code I'm using:




            public Person getSelectedProfile()
            {
                 Person retVal = (Person)this.entityManager.createQuery("SELECT DISTINCT p FROM Person p " +
                      " LEFT JOIN FETCH p.picture " +
                      " LEFT JOIN FETCH p.resume " +
                      " LEFT JOIN FETCH p.idCard " +
                 " WHERE p.id=:profileId")
                 .setParameter("profileId", this.selectedProfileId)
                 .getSingleResult();
                 
                    return retVal;
            }



            I thought polymorphism was supposed to work transparently?


            Strange thing is, when I put a breakpoint at return retVal, I'm seeing a Person object with a org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer (handler property) containing a Student target-object with all the right fields initialized.


            Is there something wrong with my lazy loading or something?



            b.



            • 3. Re: Polymorphism and properties
              lvdberg

              Hi,


              have you checked the entry in the DB and can you see the generated SQL ?


              Because a stared at your code, but I can't see anything strange! The only thing is the Layinitalizer stuff, which looks strange because everything is inside the same table (unless you have defined properties with lazy loading with @Basic)


              Leo

              • 4. Re: Polymorphism and properties
                beligum.b.beligum.org

                Whow.. I traced this back to the presence of an rss (Atom) feed in the header of the page.


                When I include this line of html in the header of a page that loads a polymorph object, it went wrong:


                <link rel="alternate" type="application/atom+xml" href="blah.rss" />



                Could this be a (very) obscure bug?

                • 5. Re: Polymorphism and properties
                  nuuh
                  Hi,

                  I have Employee, Manager.. entityes

                  @Entity
                  @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
                  @DiscriminatorColumn(name = "EmployeeType", discriminatorType = DiscriminatorType.CHAR)
                  @DiscriminatorValue("E")

                  @Table(name = "employee")
                  public class Employee implements Serializable {}

                  --------------

                  @Entity
                  @DiscriminatorValue("M")
                  public class Manager extends Employee implements Serializable {

                  --------------

                  in user table i have OneToOne Relation with Employee entity
                  and when user login to system i have to know what is the what is the employee tpye?
                  like 'E' or 'M'



                  i tryed like that:

                  System.out.println("TYPE:"+this.user.getClass().getSimpleName().toString());
                  System.out.println("TYPE:"+this.user.getEmployee().getClass().getSimpleName().toString());

                  first is gived to me class name but i didnt take class name from second code..

                  i am waiting your answer.. thanks..
                  • 6. Re: Polymorphism and properties
                    nuuh

                    i found my problem..
                    i used the same way what i wrote befoure comment..
                    so if you need you can use this way :)


                    • 7. Re: Polymorphism and properties
                      lvdberg

                      Hi,


                      Hopefully I understand you but you should define the class hierachy in another way. You can define the class User and Employee and Manager extend the User. Or - far better approach - have a User only and define a Role class.


                      There should be a ManyToMany between User and Rols. So everybody is employee, but the Manager has an additional Role. This way you will not have problems with the AuthenticationManager as provided by Seam. If you take this path, you can additionally use the Seam annotations for User and Role (see the documentation under security)


                      Leo