JPA/hibernate sorted collection @OrderBy vs @Sort

前端 未结 3 1051
深忆病人
深忆病人 2020-12-23 09:55

I would like to have a collection of child objects (here cat-kitten example) that are ordered. And keep their order on adding of new elements.

@Entity 
publ         


        
相关标签:
3条回答
  • 2020-12-23 10:15

    If you want to avoid non-standard annotations, you could make kittens use some sorted Collection implementation. This would ensure that kittens is always in sorted order. Something like this:

    @Entity 
    public class Cat {
      @OneToMany(mappedBy = "cat", cascade = CascadeType.ALL)
      @OrderBy("name ASC")
      private SortedSet<Kitten> kittens = new TreeSet<>();
    }
    

    Note that this approach also requires Kitten to implement Comparable (alternatively, you could pass a Comparator to your TreeSet constructor). Also, I'm using a Set because I'm not aware of any standard sorted List implementation and I'm assuming the Cat does not have any clones in its litter =p.

    Update: I'm not sure how picky Hibernate is with its getter/setter definitions, but with EclipseLink I've been able to remove a setter entirely and wrap the List returned by my getter in a Collections.unmodifiableList(...) call. I then defined special methods for modifying the collection. You could do the same thing and force callers to use an add method that inserts elements in sorted order. If Hibernate complains about not having the getter/setter, maybe you could change the access modifier? I guess it comes down to how far you're willing to go to avoid non standard dependencies.

    0 讨论(0)
  • 2020-12-23 10:22

    The latest version of Hibernate uses new annotations to accomplish this:

    @SortNatural
    @OrderBy("name ASC")
    private SortedSet<Kitten> kittens = new TreeSet<>();
    

    There are two parts to this:

    1. The @OrderBy annotation specifies that an order by clause should be added to the database query when fetching the related records.
    2. The @SortNatural annotation assumes that Kitten implements the Comparable interface and uses that information when constructing the TreeSet instance. Note that you can replace this with the @SortComparator annotation, which allows you to specify a Comparator class that will be passed to the TreeSet constructor.

    See documentation: https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#collections-sorted-set

    0 讨论(0)
  • 2020-12-23 10:29
    @Entity 
    public class Cat {
      @OneToMany(mappedBy = "cat", cascade = CascadeType.ALL)
      private Set<Kitten> kittens = new TreeSet<>();
    }
    

    No need to write

    @OrderBy("name ASC")

    Make Sure Kitten Class implements Comparable interface properly.

    0 讨论(0)
提交回复
热议问题