-->
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.  [ 17 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: How to order a collection property ?
PostPosted: Tue Dec 21, 2010 5:48 am 
Pro
Pro

Joined: Mon Apr 16, 2007 8:10 am
Posts: 246
I have a property that is a collection.

I mapped it so as to order it by the listOrder index, like:

Code:
        <set name="links" inverse="true" order-by="list_order">
            <key>
                <column name="category_id" />
            </key>
            <one-to-many class="com.thalasoft.learnintouch.core.domain.Link" />
        </set>


The full Hibernate mapping is:

Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Apr 18, 2010 1:03:51 PM by Hibernate Tools 3.2.1.GA -->
<hibernate-mapping>
    <class name="com.thalasoft.learnintouch.core.domain.LinkCategory" table="link_category" dynamic-insert="true" dynamic-update="true">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <version name="version" type="int">
            <column name="version" not-null="true" />
        </version>
        <property name="name" type="string">
            <column name="name" length="50" not-null="true" />
        </property>
        <property name="description" type="string">
            <column name="description" not-null="false" />
        </property>
        <set name="links" inverse="true" order-by="list_order">
            <key>
                <column name="category_id" />
            </key>
            <one-to-many class="com.thalasoft.learnintouch.core.domain.Link" />
        </set>
    </class>
</hibernate-mapping>

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Apr 18, 2010 1:03:51 PM by Hibernate Tools 3.2.1.GA -->
<hibernate-mapping>
    <class name="com.thalasoft.learnintouch.core.domain.Link" table="link" dynamic-insert="true" dynamic-update="true">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <version name="version" type="int">
            <column name="version" not-null="true" />
        </version>
        <property name="name" type="string">
            <column name="name" length="50" not-null="true" />
        </property>
        <property name="description" type="string">
            <column name="description" />
        </property>
        <property name="image" type="string">
            <column name="image" length="50" />
        </property>
        <property name="url" type="string">
            <column name="url" />
        </property>
        <property name="listOrder" type="int">
            <column name="list_order" not-null="true" />
        </property>
        <many-to-one name="linkCategory" class="com.thalasoft.learnintouch.core.domain.LinkCategory" fetch="select">
            <column name="category_id" />
        </many-to-one>
    </class>
</hibernate-mapping>


I coded a test to make sure the property is retrieved in a correct order, that is, is ordered by the listOrder index:

Code:
   @Test
   public void testCollection() {
      link0 = new Link();
      link0.setName("Thalasoft");
      link0.setImage("image0.png");
      link0.setListOrder(3);
      linkCategory0.addLink(link0);
      link1 = new Link();
      link1.setName("Libe");
      link1.setImage("image1.jpg");
      link1.setListOrder(2);
      linkCategory0.addLink(link1);
      link2 = new Link();
      link2.setName("Google");
      link2.setImage("image2.gif");
      link2.setListOrder(1);
      linkCategory0.addLink(link2);
      LinkCategory linkCategory = linkCategoryDao.findById(linkCategory0.getId(), false);
      assertEquals(3, linkCategory.getLinks().size());
      assertEquals(link2.getName(), linkCategory.getLinks().iterator().next().getName());
      assertEquals(link1.getName(), linkCategory.getLinks().iterator().next().getName());
      assertEquals(link0.getName(), linkCategory.getLinks().iterator().next().getName());
   }


But when running the test it retrieves the collection in a random order, different every build, ignoring the listOrder index:

Quote:
org.junit.ComparisonFailure: expected:<[Google]> but was:<[Thalasoft]>


If lucky, sometimes the test succeeds, only to fail on the next build.

Of course, I need the database itself to order the collection items.

I read the part on sorted collections at http://docs.jboss.org/hibernate/core/3. ... tions.html specifically:

"If you want the database itself to order the collection elements, use the order-by attribute of set, bag or map mappings.".

But could not see the solution.

Any clue ?


Top
 Profile  
 
 Post subject: Re: How to order a collection property ?
PostPosted: Tue Dec 21, 2010 7:00 am 
Pro
Pro

Joined: Mon Apr 16, 2007 8:10 am
Posts: 246
A funny thing is that if I use a dummy non existing property name as in:

order-by="dummylist_order"

the mapping is still loaded fine, the test failing but not being in error.

Looks like my attribute order-by="list_order" is simply ignored.


Top
 Profile  
 
 Post subject: Re: How to order a collection property ?
PostPosted: Tue Dec 21, 2010 8:21 am 
Pro
Pro

Joined: Mon Apr 16, 2007 8:10 am
Posts: 246
Here is the bean property:
Code:
private SortedSet<Link> links = new TreeSet<Link>();


Top
 Profile  
 
 Post subject: Re: How to order a collection property ?
PostPosted: Tue Dec 21, 2010 1:50 pm 
Pro
Pro

Joined: Mon Apr 16, 2007 8:10 am
Posts: 246
Correct me if I'm wrong but I understand now that a table with a column acting as an index to sort the rows, must be mapped as a List and not as a Set.

So, I'm now trying the following mapping:
Code:
        <list name="links" inverse="true">
            <key column="category_id" />
            <list-index column="list_order" />
            <one-to-many class="com.thalasoft.learnintouch.core.domain.Link" />
        </list>


with the bean property being:
Code:
   private List<Link> links = new LinkedList<Link>();


and the test:
Code:
   public void testCollection() {
      link0 = new Link();
      link0.setName("Thalasoft");
      link0.setImage("image0.png");
      link0.setListOrder(3);
      linkCategory0.addLink(link0);
      link2 = new Link();
      link2.setName("Google");
      link2.setImage("image2.gif");
      link2.setListOrder(1);
      linkCategory0.addLink(link2);
      link1 = new Link();
      link1.setName("Libe");
      link1.setImage("image1.jpg");
      link1.setListOrder(2);
      linkCategory0.addLink(link1);
      LinkCategory linkCategory = linkCategoryDao.findById(linkCategory0.getId(), false);
      assertEquals(3, linkCategory.getLinks().size());
      assertEquals(link2.getName(), linkCategory.getLinks().get(0).getName());
      assertEquals(link1.getName(), linkCategory.getLinks().get(1).getName());
      assertEquals(link0.getName(), linkCategory.getLinks().get(2).getName());
   }


But I still get the collection items not ordered:
Quote:
org.junit.ComparisonFailure: expected:<[Google]> but was:<[Thalasoft]>


Top
 Profile  
 
 Post subject: Re: How to order a collection property ?
PostPosted: Tue Dec 21, 2010 2:07 pm 
Pro
Pro

Joined: Mon Apr 16, 2007 8:10 am
Posts: 246
By the way, here is the method to add a link to a category:
Code:
   public List<Link> getLinks() {
      return this.links;
   }

   @SuppressWarnings("unused")
   private void setLinks(List<Link> links) {
      this.links = links;
   }

   public void addLink(Link link) {
      LinkCategory currentCategory = link.getLinkCategory();
      if (currentCategory != this) {
         if (currentCategory != null) {
            currentCategory.getLinks().remove(link);
         }
         link.setLinkCategory(this);
         this.links.add(link);
      }
   }


Top
 Profile  
 
 Post subject: Re: How to order a collection property ?
PostPosted: Wed Dec 22, 2010 2:59 am 
Regular
Regular

Joined: Fri Nov 12, 2010 4:13 am
Posts: 81
Location: India
I dont know what's the exact answer..But i can suggest something..why dont you add criteria.orderBy to your criteria while creating criteria in business class.


May be this can help you.



Chirag

_________________
Thanks & Regards,
Chirag


Top
 Profile  
 
 Post subject: Re: How to order a collection property ?
PostPosted: Wed Dec 22, 2010 2:00 pm 
Pro
Pro

Joined: Mon Apr 16, 2007 8:10 am
Posts: 246
Hi Chirag,

Thanks for your comment, but which statement should I add the order by clause to ?

The thing is, the collection is a property of an entity. The entity is retrieved by a regular findById in the generic Dao.

There is no such statement to retrieve the collection. It is retrieved alongside the entity. And lazily.


Top
 Profile  
 
 Post subject: Re: How to order a collection property ?
PostPosted: Thu Dec 23, 2010 10:41 am 
Pro
Pro

Joined: Mon Apr 16, 2007 8:10 am
Posts: 246
Any one ? It should be a fairly common problem, a collection property with its own index..


Top
 Profile  
 
 Post subject: Re: How to order a collection property ?
PostPosted: Sat Dec 25, 2010 1:27 pm 
Pro
Pro

Joined: Mon Apr 16, 2007 8:10 am
Posts: 246
Must be the Christmas break..


Top
 Profile  
 
 Post subject: Re: How to order a collection property ?
PostPosted: Sun Dec 26, 2010 11:25 am 
Pro
Pro

Joined: Mon Apr 16, 2007 8:10 am
Posts: 246
I modified the Hibernate mapping to add a cascade attribute:
Code:
        <list name="links" inverse="true" cascade="persist,merge,save-update">
            <key column="category_id" not-null="true" />
            <list-index column="list_order" base="1" />
            <one-to-many class="com.thalasoft.learnintouch.core.domain.Link" />
        </list>

but I still get the same exception:
Quote:
org.junit.ComparisonFailure: expected:<[Google]> but was:<[Thalasoft]>


I then added a flush() in the test:
Code:
      linkCategoryDao.flush();
      LinkCategory linkCategory = linkCategoryDao.findById(linkCategory0.getId(), false);
      assertEquals(3, linkCategory.getLinks().size());

but I again get the same exception:
Quote:
org.junit.ComparisonFailure: expected:<[Google]> but was:<[Thalasoft]>


This leads me to wonder if the ordering is not simply ignored by Hibernate.

Indeed, the ordering is specified using, not a bean property name, but a database column name:
Code:
            <list-index column="list_order" base="1" />


Also, in my test case, the log shows all 5 insert statements, 3 for the links and 2 for the link categories. But it does not show any sql statement corresponding to the select of the findById method. Why is that ?

If the beans are cached and never actually persisted into the database itself, then is Hibernate still doing the ordering ?


Top
 Profile  
 
 Post subject: Re: How to order a collection property ?
PostPosted: Sun Dec 26, 2010 11:54 am 
Pro
Pro

Joined: Mon Apr 16, 2007 8:10 am
Posts: 246
How come there is not one post on the forum with the list-index keyword ?

search.php?keywords=list-index&terms=all&author=&sc=1&sf=all&sk=t&sd=d&sr=posts&st=0&ch=300&t=0&submit=Search


Top
 Profile  
 
 Post subject: Re: How to order a collection property ?
PostPosted: Tue Dec 28, 2010 5:47 am 
Pro
Pro

Joined: Mon Apr 16, 2007 8:10 am
Posts: 246
I again tried with a Set instead of a List, this time like:
Code:
        <set name="links" inverse="true" order-by="list_order" cascade="all-delete-orphan">
            <key column="category_id" />
            <one-to-many class="com.thalasoft.learnintouch.core.domain.Link" />
        </set>

and
Code:
   private Set<Link> links = new LinkedHashSet<Link>();

But it did not help and the error was still:
Quote:
org.junit.ComparisonFailure: expected:<[Google]> but was:<[Thalasoft]>


Top
 Profile  
 
 Post subject: Re: How to order a collection property ?
PostPosted: Tue Dec 28, 2010 6:36 pm 
Newbie

Joined: Tue Dec 28, 2010 6:31 pm
Posts: 1
thanks for this, really helped me

cheers


Top
 Profile  
 
 Post subject: Re: How to order a collection property ?
PostPosted: Tue Dec 28, 2010 6:46 pm 
Pro
Pro

Joined: Mon Apr 16, 2007 8:10 am
Posts: 246
Do you mean you solved the same issue ?

I still haven't solved it..


Top
 Profile  
 
 Post subject: Re: How to order a collection property ?
PostPosted: Wed Dec 29, 2010 11:25 am 
Newbie

Joined: Wed Dec 29, 2010 11:20 am
Posts: 1
Hi,

Try <set name="links" inverse="true" order-by="list_order asc">


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 17 posts ]  Go to page 1, 2  Next

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.