Tuesday, May 5, 2009

Hibernate annotations sort using Comparator

Collections/Sets in Hibernate can be sorted in 2 ways:

  • One way is by Using “OrderBy” annotation (@OrderBy).
  • Second way is by using “Sort” annotation (@Sort).

The first way does the sort on the query level, meaning the SQL code that is generated for the object has the ORDER BY clause. The second way does the sort on Java.

Doing the sort on the SQL level may be more efficient, but doing the sort on Java gives us a Set (or List) that is always sorted, even if new items are added to it. In some cases we want to keep the list sorted as we add new items to it.

Using the Sort annotation is very simple, two things are needed to be done:

  • Add the @Sort annotation to the Set we would like to sort.
  • Implement a Comparator that will be used for the sort.

Here is example of 2 objects (tables):

  • The first object is called Owner. It represent a person. It’s columns are:
    • owner_id
    • first_name
    • last_name
  • The second is called Disk. It represents a music disk. It’s columns are:
    • disk_id
    • owner_id
    • title
    • artist

The relation between Owner and Disk is one-to-many. The example shows how to use the @Sort annotations to keep the disks Set sorted by the disk title.

This is the Disk class. It contains the DiskComparator:

package com.bashan.blog;
import javax.persistence.*;
import java.util.Comparator;
@Entity
@Table(name="disk")
public class Disk {
@Id
@Column(name="disk_id")
private Integer diskId;
@Column(name="title")
private String title;
@Column(name="artist")
private String artist;
@ManyToOne
@JoinColumn(name="owner_id")
private Owner owner
public Integer getDiskId() {
return diskId;
}
public void setDiskId(Integer diskId) {
this.diskId = diskId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public Disk getDisk() {
return disk;
}
public void setDisk(Disk disk) {
this.disk = disk;
}
public static class DiskComparator implements Comparator<Disk>
{
public int compare(Disk d1, Disk d2)
{
String t1 = d1.getTitle();
String t2 = d2.getTitle();
if (t1 == null && t2 == null)
{
return 0;
}
else if (t1 == null)
{
return -1;
}
else if (t2 == null)
{
return 1;
}
else
{
return t1.toLowerCase().compareTo(t2.toLowerCase());
}
} 
}
}
This is the Owner class. It contains the use of @Sort annotation:
package com.bashan.blog;
import org.hibernate.annotations.Sort;
import org.hibernate.annotations.SortType;
import javax.persistence.*;
import java.util.SortedSet;
@Entity
@Table(name="owner")
public class Owner {
@Id
@Column(name="owner_id")
private Integer ownerId;
@Column(name="first_name")
private String firstName;
@Column(name="last_name")
private String lastName;
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@JoinColumn(name="owner_id")
@Sort(type = SortType.COMPARATOR, comparator = Disk.DiskComparator.class)
private SortedSet<Disk> disks;
public Integer getOwnerId() {
return ownerId;
}
public void setOwnerId(Integer ownerId) {
this.ownerId = ownerId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public SortedSet<Disk> getDisks() {
return disks;
}
public void setDisks(SortedSet<Disk> disks) {
this.disks = disks;
}
}

You can also download the 2 classes from Here.

5 comments:

  1. Thanks. This was very helpful and the example is very clear.

    ReplyDelete
  2. @ManyToOne
    @JoinColumn(name="owner_id")
    private Disk disk;


    should be

    @ManyToOne
    @JoinColumn(name="owner_id")
    private Owner owner;

    in Disk.java

    heden

    ReplyDelete
  3. I'll use your comparator in couple of days. thanks a lot. great job.

    heden

    ReplyDelete
  4. very interesting article on sortedset hibernate

    Java Training in Chennai

    ReplyDelete