36

我想要一组有序的子对象(这里是 cat-kitten 示例)。并保持他们添加新元素的顺序。

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

  public void setKittens(List<Kitten> kittens) { this.kittens = kittens; }
  public List<Kitten> getKittens() { return kittens; } 
}

当我这样做时cat.getKittens.add(newKitten),按名称排序将被破坏。

是否可以让hibernate做保持集合始终有序的工作?通过使用@Sort hibernate注释?
@Sort 的缺点是它迫使您实现 Comparable 接口……正确的“纯 JPA”方法是什么?将所有内容保存到数据库并重新加载?将@OrderBy 和@Sort 结合起来有意义吗?

到目前为止的更新 解决方案是结合@OrderBy 和@Sort。@OrderBy 导致ORDER BY生成的 SQL 中的一个子句对性能更好(我假设 java 在插入排序容器时再次“排序”,但这应该更快,因为元素已经排序)@Sort 和一个实现Comparable的接口导致一个始终排序的容器。请注意,我使用 nowSortedSet而不是List. 这里更新的代码:

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

  public void setKittens(SortedSet<Kitten> kittens) { this.kittens = kittens; }
  public SortedSet<Kitten> getKittens() { return kittens; } 
}
4

2 回答 2

28

如果你想避免非标准的注释,你可以kittens使用一些排序的Collection实现。这将确保kittens始终按排序顺序。像这样的东西:

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

请注意,这种方法还需要Kitten实现Comparable(或者,您可以将 a 传递Comparator给您的TreeSet构造函数)。另外,我使用 aSet因为我不知道任何标准的排序List实现,并且我假设Cat它的 litter =p 中没有任何克隆。

更新: 我不确定 Hibernate 对它的 getter/setter 定义有多挑剔,但是使用 EclipseLink 我已经能够完全删除一个 setter 并将List我的 getter 返回的值包装在一个Collections.unmodifiableList(...)调用中。然后我定义了修改集合的特殊方法。您可以做同样的事情并强制调用者使用按排序顺序插入元素的 add 方法。如果 Hibernate 抱怨没有 getter/setter,也许您可​​以更改访问修饰符?我想这取决于您愿意避免非标准依赖关系的程度。

于 2013-11-10T22:38:03.757 回答
22

最新版本的 Hibernate 使用新的注解来实现这一点:

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

这有两个部分:

  1. @OrderBy注释指定order by在获取相关记录时应将子句添加到数据库查询中。
  2. @SortNatural注释假定Kitten实现了Comparable接口并在构造TreeSet实例时使用该信息。请注意,您可以将其替换为@SortComparator注释,它允许您指定Comparator将传递给TreeSet构造函数的类。

请参阅文档:https ://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#collections-sorted-set

于 2017-02-10T23:21:14.660 回答