Java Order by对不同子对象类型的一对多关系

Far*_*ook 8 java spring hibernate jpa spring-data

题

我需要根据idif ExamObjectis of对 ExamObjects 进行ExamTask排序,并根据questionNumberif it is 对其进行排序ExamQuestion。我怎样才能做到这一点?

重要的

考试将只有一组ExamTask或ExamQuestion。换句话说,一项考试不能混合使用 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;
   ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

ExamObject

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class ExamObject {    
    @Id
    private Long id;
    ...
Run Code Online (Sandbox Code Playgroud)

ExamTask

@Entity
@PrimaryKeyJoinColumn(name = "id", referencedColumnName = "id")
public class ExamTask extends ExamObject{
   ...
Run Code Online (Sandbox Code Playgroud)

ExamQuestion

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

小智 7

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

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

希望有帮助。


Mia*_*Mia 5

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

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


Sam*_*s33 2

通过将集合声明为 type并向构造函数TreeSet提供 a ,插入的项目将自动排序。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;
    }
});
Run Code Online (Sandbox Code Playgroud)