【问题标题】:Hibernate: Sorting children through a onetomany + manytoone relationHibernate:通过onetomany + manytoone关系对孩子进行排序
【发布时间】:2018-10-11 16:30:34
【问题描述】:

我有一个 Contact 实体通过 @OneToMany 关系连接到一个 ContactList 实体。然后 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;
}

Review List createdOn 字段我正在尝试按以下方式对父项进行排序:

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

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

Hibernate 似乎将引用字符串的第一部分直接放入查询中。无论我在其中输入什么错误:

原因:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:“订单子句”中的未知列“contactlis0_.created_on” 在 sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_91] 在 sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_91] 在 sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_91] 在 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 查询来按照我的意愿对它们进行排序并将其分别传递给页面,但我试图通过注释和休眠来做到这一点。

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 实际上,期望的结果是按可比性排序。但是,如果我在 SortedSet 上没有 @OrderBy 注释,则会出现编译错误:org.hibernate.AnnotationException: A sorted collection must define and ordering or sorted。那不是很好的英语,但我很确定他们的意思是我必须在那时定义排序顺序。
    • 不知怎的,我错过了你的最后一句话。我现在就试试。
    • 当我将其更改为普通的旧设置时,它会随机排序。
    • 这有很多活动的部分。如果你想使用 Hibernate,只需确保你没有在 Java 中进行任何排序(实体没有实现可比较,并且你没有为 getContactLists 返回一个 SortedSet 的实例)。
    • 为了进一步澄清,请使用带有 @OrderBy 注释的原始 Set,实体上没有 compareTo。
    【解决方案2】:

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

    这似乎不优雅,但我不知道如何使用注释在休眠中引用孩子的孩子。排序现在按照我想要的方式进行。

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

    【讨论】:

      猜你喜欢
      • 2014-03-04
      • 1970-01-01
      • 1970-01-01
      • 2022-08-13
      • 2019-02-09
      • 2017-06-07
      • 1970-01-01
      • 1970-01-01
      • 2013-06-17
      相关资源
      最近更新 更多