-->
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.  [ 5 posts ] 
Author Message
 Post subject: Sorting a Many-to-Many Set in an hbm file
PostPosted: Tue Sep 09, 2008 4:16 pm 
Newbie

Joined: Tue Sep 09, 2008 3:51 pm
Posts: 3
Location: Indianapolis
I've found people asking this question but no definitive answer as of yet:

I have two tables "speaker" & "speech_topic" plus the join table "speaker_has_topic". Each class has a java.util.Set of the other's type wit a many-to-many relationship since speakers may have multiple topics and topics may have multiple speakers. I display the results on a page with an iterator.

I have everything working well with the code below except that the list of speakers I get is in a different order each time. Since "speaker" has a column "last_name", I want to order the set by that field. I tried order-by="last_name asc" and order-by="speaker.last_name asc". Neither worked.

Is there a way to order the set vai the hbm files "set" or "many-to-many" call? Or do I have to use a SortedSet?


My current hbm files look like this:

Speaker:
Code:
<hibernate-mapping>
   <class name="friedman.data.Speaker" table="speaker">
                <id name="id" column="speaker_id">
         <generator class="native" />
      </id>
      <property name="firstName" column="first_name" />
      <property name="middleName" column="middle_name" />
      <property name="lastName" column="last_name" />

      <set name="topics" table="speaker_has_topic" order-by="topic_id asc">
         <key column="speaker_id" />
         <many-to-many column="topic_id" class="friedman.data.SpeechTopic" not-found="ignore" />
      </set>   
   </class>
</hibernate-mapping>


SpeechTopic:
Code:
<hibernate-mapping>
   <class name="friedman.data.SpeechTopic" table="speech_topic">
      <id name="id" column="topic_id">
         <generator class="native" />
      </id>
      <property name="name" />


      <set name="speakers" table="speaker_has_topic">
         <key column="topic_id" />
         <many-to-many column="speaker_id" class="friedman.data.Speaker" not-found="ignore" />
      </set>                  
   </class>
</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 12, 2008 10:12 am 
Beginner
Beginner

Joined: Tue Sep 09, 2008 5:42 am
Posts: 22
Location: Romania
Ciao,

I use NHibernate and the way I treat these issues of Sorting is in code by adding an Order to the criteria I build, like this:

ICriteria crit=NHSession.Instance.CreateCriteria(typeof(MyType)).AddOrder(new Order("PropertyName",true));
IList returnedList=crit.List<myType>();

The returned list will be sorted (Asc=true Desc=false) in order of your Property passed to the Order object.

Hope it helps you find the right solution for your problem!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 12, 2008 12:59 pm 
Newbie

Joined: Tue Sep 09, 2008 3:51 pm
Posts: 3
Location: Indianapolis
Thanks for the recommendation but that creates another problem:
I need to filter out the Speakers that are in the identified SpeechTopic's "speakers" set or have this SpeechTopic in its "topics" set. Either way because as a many-to-many relationship they have sets of each other.

Code:
Session sess = HibernateSession.openSession();
Criteria crit = sess.createCriteria(Speaker);
crit.addOrder(Order.desc("lastName"));
java.util.List speakers = new ArrayList(topic.getSpeakers());


This code works for returning a list of ordered speakers but it does not filter out those associated with the identified topic. I don't know how to set up a restriction that pulls only Speakers that have a certain SpeechTopic in its topics set.

It just seemed easier to order the speakers being propagated into an instance of SpeechTopic as part of the SQL call process. No?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 17, 2008 4:23 am 
Beginner
Beginner

Joined: Tue Sep 09, 2008 5:42 am
Posts: 22
Location: Romania
Ciao,

From what I understand the best solution would be to have three clases: one for speakers, one for speech_topic and one with the relation between them. Doing this you will split your many-to-many relation in two many-to-one realtions mapped in the link class. After that you create your criteria on the link class, filter after the field you want and add the order after that.

If you think this implies to many modifications write another post and we can think together how to solve the problem with your current architecture.

Good luck!


Top
 Profile  
 
 Post subject: Solution
PostPosted: Wed Sep 17, 2008 10:56 am 
Newbie

Joined: Tue Sep 09, 2008 3:51 pm
Posts: 3
Location: Indianapolis
Well I solved my problem. Part of my original problem was in insisting to use a Set as opposed to using another type of Collection.

What I Did:
What I was trying to do was have my the associated Set of Speaker within SpeechTopic to be pre-sorted so that whenever I referenced an instance of SpeechTopic, I would be able to simply be able to pull that instance's Set speakers and it would be ready to go. This may still be possible as I will discuss later.
Instead what I did was use tomaandtoma's advise and used a seperate call to pull a List that was sorted. I used the example from http://www.hibernate.org/hib_docs/reference/en/html/querycriteria.html#querycriteria-associations to place a secondary Criteria on the each Speaker's set of SpeechTopics, as such:

Code:
Session sess = HibernateSession.openSession();
Criteria crit = sess.createCriteria(Speaker.class);
[b]crit.createCriteria("topics").add(Restrictions.eq("id", Long.valueOf(id.longValue())));[/b]
crit.addOrder(Order.asc("lastName"));
request.setAttribute("speakers", crit.list());

This pulls a List of all Speakers who have the given SpeechTopic in their Set "topics".

What I Possibly Could Have Done:
I am not very familiar with these Collection types and I am using another person's code as my basis. The example code used Sets to handle these many-to-many object collections. I mistakenly took a List to be an ordered array of Strings.
What I might do in the future is to swap out my Sets for Lists, fill it with Composite-elements, and see if I can sort/order it that way.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 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.