4 Replies Latest reply on Jan 11, 2007 2:46 PM by joe.marques

    EJB QL/ JPQL and search for inheritance

    Joachim Rosskopf Newbie

      Hello,

      I have a problem with creating a QL expression for some of my entities. First of all I have an entity "Item" which has a ManyToMany reference to 0..* "Tags" But Tag is just a base class for more complex Entities such as "PlaceMark"

      @Entity
      public class Item implements Serializable{
       private static final long serialVersionUID = -6240744395949853067L;
       .
       .
       .
       /**
       * Get a list of tags associated with the item
       * @return list of tags associated with the item
       */
       @ManyToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE})
       public List<Tag> getTags() {
       return tags;
       }
       public void setTags(List<Tag> tags) {
       this.tags = tags;
       }
      }
      


      @Entity
      @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
      @DiscriminatorColumn(name="dtype", discriminatorType=DiscriminatorType.STRING)
      @DiscriminatorValue("Tag")
      public class Tag implements Serializable{
       private static final long serialVersionUID = 2432906233376577675L;
      
       long gid;
       String name;
       List<Item> items;
      
       @Id
       @GeneratedValue
       public long getGid() {
       return gid;
       }
       public void setGid(long gid) {
       this.gid = gid;
       }
      
       public String getName() {
       return name;
       }
       public void setName(String value) {
       this.name = value;
       }
      
       @ManyToMany(mappedBy="tags", cascade={CascadeType.PERSIST, CascadeType.MERGE})
       public List<Item> getItems() {
       return items;
       }
       public void setItems(List<Item> items) {
       this.items = items;
       }
      }
      


      @Entity
      @DiscriminatorValue("PlaceMark")
      public class PlaceMark extends Tag implements Serializable {
       private static final long serialVersionUID = -6646702308712255267L;
      
       boolean visibibilty;
       LookAt lookAt;
       Point point;
      
       public PlaceMark() {
       super.setName("PlaceMark");
       }
      
       @Embedded
       public LookAt getLookAt() {
       return lookAt;
       }
       public void setLookAt(LookAt lookAt) {
       this.lookAt = lookAt;
       }
      
       @Embedded()
       public Point getPoint() {
       return point;
       }
       public void setPoint(Point point) {
       this.point = point;
       }
      
       public boolean isVisibibilty() {
       return visibibilty;
       }
       public void setVisibibilty(boolean visibibilty) {
       this.visibibilty = visibibilty;
       }
      
       public void setName(String value) {
       }
      
      }
      


      So now my question, how can I search for items annotaded with different types of tags in the "Tag" class hierachy?

      Thank you in advance.
      Regards
      ---
      Joachim

        • 1. Re: EJB QL/ JPQL and search for inheritance
          Andrew Dale Newbie

          Hi Joachim,

          In a EJB3 QL query you can query the Discriminator Value in the where section of the query. For example:

          WHERE tag.class = <discriminator value>


          This is how i have managed to restrict results based on a Discriminator Value before.


          Cheers,

          Andy



          • 2. Re: EJB QL/ JPQL and search for inheritance
            Joachim Rosskopf Newbie

            Hi Andy (and everybody else),

            thank you for fast reply.

            That works well and is a first step torwards a solution.
            But I still need access to properties of the subclasses in the collection.

            Speaking in plain java it would be condition like this:

            if (tag instanceof PlaceMark && ((PlaceMark)tag).getPoint().getX() == 0.0d)
            


            So is it possible to do something like a cast? I read through Mr Monsons-Haefels and Mr Brukes book an found nothing useful.

            Regards
            ---
            Joachim

            • 3. Re: EJB QL/ JPQL and search for inheritance
              Andrew Dale Newbie

              Joachim,

              I have never attmepted to do an instanceof with the inheritance type of a single table per hierarchy. Prehaps you should investigate some other strategies, namely table per subclass as i think this will provide you with the functionality you would like, like so:

               //create query
               Query tmpQuery = mEntityManager.createQuery("FROM Tag t");
              
               //get query result
               ArrayList<Tag> queryResult = (ArrayList<Tag>)tmpQuery.getResultList();
              
               //get iterator
               Iterator it = testList.iterator();
              
               //loop
               while (it.hasNext()) {
               Tag element = (Tag) it.next();
              
               if(element instanceof PlaceMark) {
               //DO STUFF :-)
               }
               }
              


              In your top level parent class you just need to annotate like so:

              @Inheritance(strategy = InheritanceType.JOINED)


              and i just have a getter and setter for the id in this parent class, and not in the sub-classes(children). All you should need to do in the children classes is just extend the parent class.

              To persist, just create and persist a child object and it automatically create and persists the parent objet with the correct attributes.


              Cheers,

              Andy

              • 4. Re: EJB QL/ JPQL and search for inheritance
                Newbie

                 

                "jrosskopf" wrote:


                Speaking in plain java it would be condition like this:
                if (tag instanceof PlaceMark && ((PlaceMark)tag).getPoint().getX() == 0.0d)
                


                ---
                Joachim


                Joachim, did you ever find a way to do this at the JPQL level?