【问题标题】:Java Order by on one to many relationship with different child object typeJava按与不同子对象类型的一对多关系排序
【发布时间】:2015-06-26 03:25:57
【问题描述】:

问题

如果ExamObject 属于ExamTask,我需要根据id 对ExamObjects 进行排序,如果它是ExamQuestion,则根据questionNumber 对其进行排序。我该怎么做?

重要

考试将只有一组ExamTaskExamQuestion。换句话说,一项考试不能同时包含 ExamTask 和 ExamQuestion。

背景信息

我有一个名为Exam 的实体类,该类可以包含一个或多个ExamObject 实体。

@Entity
public class Exam {
   @OneToMany(mappedBy = "exam" ...)
   @OrderBy("id") //I need to order this by question number if its ExamQuestion
   private Set<ExamObject> objects;
   ...
}

ExamObject 可以有以下两种类型,使用JOINED

  1. ExamTask 扩展 ExamObject
  2. ExamQuestion 扩展 ExamObject 并有一个名为 questionNumber 的列

ExamObject

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class ExamObject {    
    @Id
    private Long id;
    ...

ExamTask

@Entity
@PrimaryKeyJoinColumn(name = "id", referencedColumnName = "id")
public class ExamTask extends ExamObject{
   ...

ExamQuestion

@Entity
@PrimaryKeyJoinColumn(name = "id", referencedColumnName = "id")
public class ExamQuestion extends ExamObject{
   @Column(name = "question_number")
   private Integer questionNumber;
   ...

【问题讨论】:

  • 出于好奇,尝试复制您的问题,但我似乎无法使映射工作。因此在这里发布了另一个问题stackoverflow.com/questions/29764533/…
  • 不知道允许在代码中使用魔法(OrderBy 注释)。谢谢这位好人。

标签: java spring hibernate jpa spring-data


【解决方案1】:

通过将集合声明为TreeSet 类型并向构造函数提供Comparator,插入的项目将自动排序。

new TreeSet<ExamObject>(new Comparator<ExamObject>(){

    @Override
    public int compare(ExamObject a, ExamObject b){
        int q1 = 0, q2 = 0;
        if(a instanceof ExamQuestion){
            q1 = ((ExamQuestion)a).questionNumber;
            if(b instanceof ExamQuestion){
                q2 = ((ExamQuestion)b).questionNumber;
            }else{
                q2 = ((ExamTask)b).id;
            }
        }else{
            q1 = ((ExamTask)a).id;
            if(b instanceof ExamQuestion){
                q2 = ((ExamQuestion)b).questionNumber;
            }else{
                q2 = ((ExamTask)b).id;
            }
        }
        if(q1 == q2) return 0;
        else return q1 < q2  ? -1 : 1;
    }
});

【讨论】:

  • 这太棒了。非常感谢。 :) 我会赞成你的答案,但会等待一段时间而不选择它,看看是否有任何其他可能性可以使用一些注释在数据库本身中运行逻辑。我正在将我的项目代码切换为您现在建议的内容。 :)
  • @FarajFarook 如果您认为我提供了最佳答案,请将其标记为正确,以便人们知道它已得到适当的回答。
【解决方案2】:

我相信您的问题是您在实体中使用了 Set。 A Set 不会维持秩序。当您的关系被加载时,该集合将不保证插入顺序。尝试改用列表。 List 将保持插入顺序。

@Entity
public class Exam {
   @OneToMany(mappedBy = "exam" ...)
   @OrderBy("id") //I need to order this by question number if its ExamQuestion
   private List<ExamObject> objects;
   ...
}

希望对您有所帮助。

【讨论】:

  • 在 Set 集合上使用 @OrderBy 没问题。
【解决方案3】:

我将 @OrderBy 与 Set 一起使用,效果很好。

@OneToMany(mappedBy = "mailing", fetch = FetchType.LAZY)
@OrderBy("documentPrintOrder ASC")
private Set<MailingDocsEntity> mailingDocs = new HashSet<MailingDocsEntity>();

【讨论】:

  • 这个对我有用。我必须将返回的 POJO(此处为 mailingDocs)转换为 VO,因此使用 List 代替 Set 以确保保留插入顺序。
猜你喜欢
  • 2023-04-10
  • 2013-08-24
  • 2011-11-06
  • 1970-01-01
  • 1970-01-01
  • 2011-01-26
  • 2014-07-02
  • 1970-01-01
  • 2016-04-16
相关资源
最近更新 更多