0

What is the best way to query an Object and return its list attributes in a sorted list?

Example:

Given the scenario below, what is the best way to do a Groups query, by bringing: the list of Items ordered by name and (for each item) the list of StateItem ordered by the Description of StateObject?

public class Group {

    // ...

    @Fetch(FetchMode.JOIN)
    @OneToMany(mappedBy = "group")
    private List<ItemGroup> itemList;

    // ...
}

public class ItemGroup {

    // ...

    @JoinColumn(name="ID_GROUP", referencedColumnName="ID_GROUP")
    @ManyToOne
    private Group group;

    @Fetch(FetchMode.JOIN)
    @OneToMany(mappedBy = "item")
    private List<StateItem> stateList;

    // ...
}

public class StateItem {

    // ...

    @JoinColumn(name="ID_ITEM", referencedColumnName="ID_ITEM")
    @ManyToOne
    private ItemGroup item;

    @JoinColumn(name="CD_STATE", referencedColumnName="CD_STATE")
    @ManyToOne
    private StateObject state;

    // ...

}

public class StateObject {

    // ...

    @Column(name="DE_STATE_OBJECT", length=255) 
    private String description;

    // ...
}

PS: I think I can't use @OrderBy because I have to sort by child attributes, as in the StateObject example. And the solution with @SortNatural or @SortComparator isn't performatic. Can I do that work using only HQL or Criteria?

Victor Soares
  • 757
  • 1
  • 8
  • 34

2 Answers2

0

You can use org.hibernate.annotations.@SortNatural if StateItem implements comparable or you can use org.hibernate.annotations.@SortComparator and provide a comparator.

NOTE : This solution does in-memory sorting which is different than ordering (as provided by @OrderBy) which is applied during the SQL SELECT.

Lucas Oliveira
  • 3,357
  • 1
  • 16
  • 20
0

I recommend you to use the @SortComparator annotation which accepts a default value the class implementing Comparator<T>.

@Fetch(FetchMode.JOIN)
@SortComparator(StateItemComparator.class)
@OneToMany(mappedBy = "item")
private List<StateItem> stateList

Its method should define the comparing strategy.

public class StateItemComparatorComparator implements Comparator<StateItem> {
    @Override
    public int compare(StateItem s1, StateItem s2) {
        return b1.getState().getDescription().compareTo(b2.getState().getDescription());
    }
} 
Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
  • @SortComparator only works for Set or Map, not for List. This is mentioned in the Javadoc and also in this issue: https://hibernate.atlassian.net/browse/HHH-9304 – Stephanie Sep 07 '22 at 14:04