6 Replies Latest reply on Jul 11, 2007 5:24 AM by lcoetzee

    Class type issue

    lcoetzee

      Hi,

      I have quite an interesting issue (which at this point has me stumped).

      I have a class Service that has a one-to-many to Topic (which is a base clase). Topic is extended into three other (CMSTopic, DFTopic and MMTopic).
      Service

      @Entity
      @Name("service")
      @Table(name = "service")
      public class Service implements Serializable {
      private Map<Integer,Topic> topics = new HashMap<Integer,Topic>();
      
      @OneToMany(mappedBy = "service")
       @MapKey(name="id")
       public Map<Integer,Topic> getTopics() {
       return topics;
       }
      }


      Topic


      @Entity
      @Name("topic")
      @Table(name = "topic")
      @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
      @DiscriminatorColumn(name = "topic_type", discriminatorType = DiscriminatorType.STRING)
      
      public class Topic implements Serializable {
      private Service service;
      @ManyToOne(fetch=FetchType.LAZY)
       public Service getService() {
       return service;
       }
      }
      
      

      and the extended classes e.g. CMSTopic
      @Entity
      @Name("cmsTopic")
      @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
      @DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING)
      @DiscriminatorValue("CMS")
      public class CMSTopic extends Topic {
      }


      When I do a service.getTopics().values() the correct subclasses of Topic is returned. But for some reason the instance type is weird.. I get the following when doing an getClass() on each element in the returned map:
      class csir.structure.par.DFTopic
      class csir.structure.par.CMSTopic
      class csir.structure.par.Topic_$$_javassist_227
      class csir.structure.par.CMSTopic

      Does anybody have an idea of why only one of these would be Topic_$$_javassist_227 while the others are the correct type ?

      Thanks

      Louis



        • 1. Re: Class type issue

           


          Does anybody have an idea of why only one of these would be Topic_$$_javassist_227 while the others are the correct type ?


          No need to worry, your class has only been bytecode-manipulated by Seam(I guess) with javassist, which is used to enrich your class with additional features:
          http://labs.jboss.com/javassist/

          • 2. Re: Class type issue
            lcoetzee

            Hmmm.. but the problem comes in later. I do

            <f:subview
            rendered="#{currTopic.class.name eq 'csir.structure.par.CMSTopic'}">
             bla bla bla
            
            


            Which works very well to display a specific thing based on the class type. Issue is that because of this manipulation, those that have been manipulated are of the wrong type....

            So why are only some of them manipulated ?

            Very curious.

            L


            • 3. Re: Class type issue
              pmuir

              I would guess this is Hibernate using proxies to support lazy fetching. Take a look at Seam.getEntityClass for how we deal with this in Seam (its a very simple deproxy). You could wrap this up in a facelets function...

              • 4. Re: Class type issue
                lcoetzee

                I have made some progress with your suggestion.. (e.g. implemented a facelets function). Unfortunately the getEntityClass returns the base class and not the inherited class.. e.g

                 Executing deproxy on csir.structure.par.Topic_$$_javassist_226 -->csir.structure.par.Topic


                In this case the deproxy should have shown
                 Executing deproxy on csir.structure.par.Topic_$$_javassist_226 -->csir.structure.par.CMSTopic


                Any idea of how to get the inherited type out of the proxied class ?

                Thanks

                L


                • 5. Re: Class type issue
                  gavin.king

                  There is a method call in Hibernate, somewhere, perhaps a static method on the class named Hibernate.

                  • 6. Re: Class type issue
                    lcoetzee

                    Hmm... trying:

                    Class<?> deproxied = org.hibernate.Hibernate.getClass(clazz);


                    results in :

                    Executing deproxy on csir.structure.par.Topic_$$_javassist_21 -->java.lang.Class


                    which is not quite what I had in mind ;-). I need to get the subclass of Topic.

                    L