JPA – 需要在SortedSet上使用OrderBy

huangapple go评论93阅读模式
英文:

JPA - OrderBy required with SortedSet

问题

为什么需要对 SortedSet 关系进行排序注释,比如 Hibernate 的 @SortNatural@OrderBy

如果默认使用自然排序,会更好。

英文:

Why SortedSet relationship required sorting annotions like hibernate-specific @SortNatural or @OrderBy ?

Could be great if natural ordering was used by default.

答案1

得分: 2

在JPA-2.2(JSR-338)的第2.2章中定义如下:

无论实体类是否遵循上述的JavaBeans方法约定,以及是使用字段访问还是属性访问,集合值持久字段和属性必须根据以下集合值接口之一来定义:java.util.Collectionjava.util.Setjava.util.Listjava.util.Map。应用程序可以使用集合实现类型来初始化字段或属性,然后将实体持久化。一旦实体变为托管状态(或脱离托管状态),后续访问必须通过接口类型进行

然后,在检索数据到@OneToMany映射字段时,持久性提供程序实现可以对给定字段使用任何相应的实现类。因此,如果映射的实体定义了一个@OneToMany List,持久性提供程序可以使用ArrayList或任何其他具体的List实现来分配字段,无论是否有序。对于未提及的接口,持久性提供程序可能会接受映射,但不必遵守它,并且不保证使用的实现方式。

@SortNatural专有注解指示Hibernate使用集合类型的有序实现,该实现将使用实体的“自然比较器”对元素进行排序。如果包含的实体类型实现了Comparable接口,则比较器将是对给定集合进行排序的“自然”比较方法。

请注意,某些持久性提供程序实现可能会或可能不会重用实例化的字段来填充集合,因此,如果您为List或Set声明和实例化了具有给定有序实现的字段,则尽管没有使用特定于Hibernate的注解,它可能已经被排序。

另一方面,@OrderBy注解是与提供程序无关的,并定义了在检索到的列表或集合上必须遵守的顺序,但其实现受数据库对字段排序方式的限制。检索到的集合可以使用保留从数据库中获取数据的顺序的任何实现,但不会使用Comparable接口在检索后重新排序数据,就像@SortNatural一样。

这两种方法都有各自的优势和问题,因此您必须验证您的用例,并决定是否对点解层面的排序至关重要。

英文:

As defined in chapter 2.2 of JPA-2.2 (JSR-338):

> Collection-valued persistent fields and properties must be defined in terms of one of the following collection-valued interfaces regardless of whether the entity class otherwise adheres to the JavaBeans method conventions noted above and whether field or property access is used: java.util.Collection, java.util.Set, java.util.List, java.util.Map. The collection implementation type may be used by the application to initialize fields or properties before the entity is made persistent. Once the entity becomes managed (or detached), subsequent access must be through the interface type.

Then, when retrieving data to an @OneToMany mapped field, a persistence provider implementation may use any corresponding implementation class for the given field. So, if a mapped entity defines a @OneToMany List, the persistence provider may assign the field with an ArrayList or any other concrete implementation of list, ordered or not. For interfaces not mentioned, the persistence provider may accept the mapping, but it is not required to respect it and there are no guarantees about the implementation used.

The @SortNatural proprietary annotation instructs Hibernate to use an ordered implementation of the collection type that will use the "natural comparator" of the entity to order the elements. If the contained entity type implements Comparable interface, that comparator will be the "natural" comparison method to order the given collection.

Be aware that some persistence provider implementations may or may not reuse the instantiated field to populate the collection, so, if you declared and instantiated the field with a given ordered implementation for the List or Set, it may be already ordered despite the lack of use of a hibernate-specific annotation.

The @OrderBy annotation, on the other hand, is provider agnostic and defines an order that must be respected on the retrieved list or set, but it's implementation is limited by how the database will order the field. The retrieved collection may use any implementation that preserves the order in which the data came from the database, but does not use the Comparable interface to reorder data after retrieval, as @SortNatural would.

Both approaches have their strength and hiccups, so you have to verify your use case and decide if this ordering is critical to the point of relieving it to your data layer.

huangapple
  • 本文由 发表于 2020年4月7日 20:58:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/61080580.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定