Techspace

IT happens only in IT

Sorting Hibernate Set using a comparator

Collection mappings in Hibernate can be configured to sort using a specific comparator.

Consider the following mapping

<hibernate-mapping>
<class name="com.example.Person" table="PERSON">
......

<set name="bankAccounts" lazy="true" cascade="all,delete-orphan" inverse="true" sort="natural">
	<key>
		<column name="BANK_ACCOUNT_ID" precision="29" scale="0" not-null="true" />
	</key>
	<one-to-many class="com.example.BankAccount" />
</set>

......
</class>
</hibernate-mapping>

In the example above Hibernate will order the bankAccounts set according to their natural order. If the BankAccout class implements Comparable interface, compareTo method will be used to sort the Set.

What if you want to sort the set differently? What if you want to use a comparator to sort the set.
The sort attribute can have three possible values

The first option is

 <set name="bankAccounts" lazy="true" cascade="all,delete-orphan" inverse="true" sort="natural">

which sorts by natural order

the second option is

 <set name="bankAccounts" lazy="true" cascade="all,delete-orphan" inverse="true" sort="unsorted">

which tells Hibernate that the Set needs not to be sorted

and the third option is

 <set name="bankAccounts" lazy="true" cascade="all,delete-orphan" inverse="true" sort="comparatorClass">

where you specify what comparator should be used to sort the Set.

Let’s see it through code example. For example suppose class BankAccount is defined as below

package com.example;
//import statements

public class BankAccount implements Comparable<BankAccount>, Serializable{

private String accountName;
private String accountShortName;
//getter and setter methods

    public int compareTo(BankAccount that) {

        final int BEFORE = -1;
        final int AFTER = 1;

        if (that == null) {
            return BEFORE;
        }

        Comparable thisAccountName = this.getAccountName();
        Comparable thatAccountName = that.getAccountName();

        if(thisAccountName == null) {
        	return AFTER;
        } else if(thatAccountName == null) {
        	return BEFORE;
        } else {
        	return thisAccountName.compareTo(thatAccountName);
        }
    }
}

In this case sort=”natural” will sort using the above compareTo method which compares the accountName to sort.
Now suppose you want that for this specific mapping you want the collection to be sorted by, say, accountShortName. You will define a Comparator like this

package com.example;
//import statements
public class BankAccountShortNameComparator implements Comparator<BankAccount>{
	public int compare(BankAccount o1, BankAccount o2) {
		if(o1!=null && o2!=null && o1.getAccountShortName()!=null && o2.getAccountShortName()!=null) {
			return o1.getAccountShortName().compareTo(o2.getAccountShortName());
		}
		if(o1!=null && o2!=null) {
			return o1.compareTo(o2);
		}

		return 0;
	}
}

Then your mapping will say something like this

	<set name="bankAccounts" lazy="true" cascade="all,delete-orphan" inverse="true" sort="com.example.BankAccountShortNameComparator">

In this way Hibernate will use your custom Comparator to sort the set

November 10, 2008 Posted by | Hibernate | , , | 11 Comments

   

Follow

Get every new post delivered to your Inbox.