-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: help with constructing a query with criteria on associations
PostPosted: Tue May 10, 2011 11:10 am 
Newbie

Joined: Mon Apr 04, 2011 3:41 pm
Posts: 12
Hey Folks,

I'm having trouble constructing a Hibernate query and I'm hoping to get some assistance here. :)

I have an object named FlashCard which has associated objects named Tags. A FlashCard can have one or more Tags (kind of like a Delicious bookmark can be assigned multiple tags).

I'm trying to write a query that returns all FlashCards that are assigned specific multiple Tags. For example, I would like to query for all FlashCards that are assigned both "tag2" and "tag4".

I'm not sure how best to explain it. I'll include my mappings and relevant code below to hopefully give you a better picture of what I'm trying and currently failing to do.

The code below is a simplified version of what I'm trying to do. This code works if I specify a single Tag.

Code:
   @Test
   public void getFlashCardsForTwoTags() {

      // Ask for a session using the JDBC information we've configured
       Session session = sessionFactory.openSession();

      Criteria criteria = session.createCriteria(FlashCard.class);
      Criteria tagCriteria = criteria.createCriteria("tags");
      tagCriteria.add(Restrictions.eq("name", "tag2"));
      tagCriteria.add(Restrictions.eq("name", "tag4"));

      // populate FlashCard object with the query result
      @SuppressWarnings("unchecked")
      List<FlashCard> flashCardList = criteria.list();
      
      assertTrue("Expected a Flash Card list", flashCardList.size() > 0);
      logger.debug("FlashCard list size: " +  flashCardList.size());
   }


If I run the above code with multiple Tags, the following query is generated
Code:
select this_.FLASHCARD_ID as FLASHCARD1_2_1_, this_.QUESTION as QUESTION2_1_, this_.ANSWER as ANSWER2_1_, tags3_.FLASHCARD_ID as FLASHCARD2_2_, tag1_.TAG_ID as TAG1_, tag1_.TAG_ID as TAG1_0_0_, tag1_.NAME as NAME0_0_
from FLASHCARD this_ inner join FLASHCARD_TAGS tags3_ on this_.FLASHCARD_ID=tags3_.FLASHCARD_ID inner join TAG tag1_ on tags3_.TAG_ID=tag1_.TAG_ID
where tag1_.NAME=? and tag1_.NAME=?


Code:
<hibernate-mapping>
   <class name="org.robbins.flashcards.model.FlashCard" table="FLASHCARD">
      <id name="flashCardId" type="int" column="FLASHCARD_ID">
         <meta attribute="scope-set">public</meta>
         <generator class="native" />
      </id>
      <property name="question" type="string">
         <meta attribute="use-in-tostring">true</meta>
         <column name="QUESTION" not-null="true" unique="true" />
      </property>
      <property name="answer" type="text">
         <meta attribute="use-in-tostring">true</meta>
         <column name="ANSWER" not-null="true" />
      </property>
      <set name="tags" table="FLASHCARD_TAGS">
         <meta attribute="field-description">Tags for this FlashCard</meta>
         <key column="FLASHCARD_ID" />
         <many-to-many class="org.robbins.flashcards.model.Tag"
            column="TAG_ID" />
      </set>
   </class>
</hibernate-mapping>


Code:
<hibernate-mapping>
   <class name="org.robbins.flashcards.model.Tag" table="TAG">
      <id name="tagId" type="int" column="TAG_ID">
         <meta attribute="scope-set">public</meta>
         <generator class="native" />
      </id>
      <property name="name" type="string">
         <meta attribute="use-in-tostring">true</meta>
         <column name="NAME" not-null="true" unique="true" />
      </property>
      <set name="flashcards" table="FLASHCARD_TAGS" inverse="true">
         <meta attribute="field-description">FlashCards for this Tag</meta>
         <key column="TAG_ID" />
         <many-to-many class="org.robbins.flashcards.model.FlashCard"
            column="FLASHCARD_ID" />
      </set>
   </class>
</hibernate-mapping>


As you can see below, FlashCard_ID '1' and '2' are both assigned Tags '2' and '4'
Code:
mysql> select * from flashcard;
+--------------+------------+----------+
| FLASHCARD_ID | QUESTION   | ANSWER   |
+--------------+------------+----------+
|            1 | Question 1 | Answer 1 |
|            2 | Question 2 | Answer 2 |
|            3 | Question 3 | Answer 3 |
+--------------+------------+----------+
3 rows in set (0.00 sec)

mysql> select * from tag;
+--------+------+
| TAG_ID | NAME |
+--------+------+
|      1 | tag1 |
|      2 | tag2 |
|      3 | tag3 |
|      4 | tag4 |
|      5 | tag5 |
+--------+------+
5 rows in set (0.00 sec)

mysql> select * from flashcard_tags;
+--------+--------------+
| TAG_ID | FLASHCARD_ID |
+--------+--------------+
|      2 |            1 |
|      3 |            1 |
|      4 |            1 |
|      2 |            2 |
|      4 |            2 |
|      5 |            2 |
+--------+--------------+
6 rows in set (0.00 sec)


Top
 Profile  
 
 Post subject: Re: help with constructing a query with criteria on associations
PostPosted: Tue May 10, 2011 4:45 pm 
Newbie

Joined: Mon Apr 04, 2011 3:41 pm
Posts: 12
Folks, here's an example of SQL that would return the results I'm looking for.

How can I create the Hibernate code for this? Any help is greatly appreciated.

Code:
SELECT  f.*
FROM    (
        SELECT  flashcard_id
        FROM    tags t
        JOIN    flashcard_tags ft
        ON      ft.tag_id = t.tag_id
        WHERE   t.name IN ('tag2', 'tag4')
        GROUP BY
                flashcard_id
        HAVING  COUNT(*) = 2
        ) ft
JOIN    flashcard f
ON      f.flashcard_id = ft.flashcard_id


Top
 Profile  
 
 Post subject: Re: help with constructing a query with criteria on associations
PostPosted: Wed May 11, 2011 11:50 am 
Newbie

Joined: Mon Apr 04, 2011 3:41 pm
Posts: 12
I was able to solve my problem by using the examples on this web page.

http://www.sergiy.ca/how-to-write-many- ... hibernate/


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.