Hibernate:通过onetomany + manytoone关系对孩子进行排序

时间:2018-05-01 16:03:29

标签: spring hibernate sorting spring-data-jpa parent-child

我有一个通过@OneToMany关系连接到ContactList实体的Contact实体。然后,ContactList实体通过@ManyToOne连接到Review List实体。 ContactList实体具有与列表上的联系人相关的数据。我需要通过Review List中的createdOn时间戳对Contact中的ContactList子项进行排序。我不确定这是可能的。

联络实体

@OneToMany(mappedBy = "contact")
@OrderBy("created_on DESC") <-- This does not work.
private SortedSet<ContactList> contactLists;

ContactList实体:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "LIST_ID")
private ReviewList reviewList;

ContactList compareTo:

@Override
public int compareTo(ContactList b) {
    if (this.getReviewList().getCreatedOn().getTime() == b.getReviewList().getCreatedOn().getTime()) {
        log.error("Two review lists have the exact same created time???");
        return 0;
    }

    return this.getReviewList().getCreatedOn().getTime() < b.getReviewList().getCreatedOn().getTime() ? -1 : 1;
}

查看列表createdOn字段我正在尝试按父级排序:

@Column(name="CREATED_ON", updatable=false)
private Timestamp createdOn;

我在没有@OrderBy表示法的情况下尝试过它,它不会编译。但是我试图在报价中提出的所有内容都失败了。我已经尝试过contactList,如图所示,reviewList,reviewList.createdOn,reviewList_createdOn以及其他一些非常愚蠢的人。

似乎Hibernate正在使用引用字符串的第一部分并将其直接放入查询中。无论我把它放在哪里都有错误:

  

引起:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:未知列&#39; contactlis0_.created_on&#39;在&#39; order子句&#39;       at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)〜[na:1.8.0_91]       at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)〜[na:1.8.0_91]       at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)〜[na:1.8.0_91]       at java.lang.reflect.Constructor.newInstance(Constructor.java:423)〜[na:1.8.0_91]       在com.mysql.jdbc.Util.handleNewInstance(Util.java:425)〜[mysql-connector-java-5.1.44.jar:5.1.44]       在com.mysql.jdbc.Util.getInstance(Util.java:408)〜[mysql-connector-java-5.1.44.jar:5.1.44]       在com.mysql.jdbc.SQLError.createSQLException(SQLError.java:943)〜[mysql-connector-java-5.1.44.jar:5.1.44]

当然它确实如此,因为我试图引用另一个表中的字段。它需要在两者之间进行某种JoinColumn。

有没有办法做到这一点?我可能会编写一个自定义的JPQL查询来对它们进行排序,并将其分别传递给页面,但我试图用注释和休眠来完成。

2 个答案:

答案 0 :(得分:0)

我相信导致问题的原因是您正在使用SortedSet。无论hibernate如何插入值,它们都将根据SortedSet的合约进行排序。除非您在 ContactList 上实现了 Comparable ,否则这将是ContactList的自然顺序。如果您已实现Comparable,那么您的列表将根据该实现进行排序。我不认为这是你想要的结果。

如果您希望数据库执行排序,请尝试将您的集合定义为 Set

答案 1 :(得分:0)

到目前为止,我的解决方案是添加一个&listHcreated_on&#39;将字段添加到ContactList对象,然后更新数据,以便每个记录都具有ReviewList created_on日期。然后每当我在数据库中创建一个新的ContactList时,我只需将其设置为审阅列表的创建日期。我不太喜欢将相同的数据保存在两个位置,但我无法绕过它。

看起来不太优雅,但我无法弄清楚如何使用注释在hibernate中引用孩子的孩子。排序现在按照我想要的方式运行。

如果其他人有更好的解决方案,我不会接受这个答案。