Java Order one at a time for many relationships with different types of child objects
Question
I need to sort the ExamObjects according to id
if it ExamObject
has ExamTask
and sort it according to questionNumber
if it has ExamQuestion
. How can i do this?
Attention!
The exam will only have a set of ExamTask
or ExamQuestion
. In other words, a single exam cannot have a mixture of ExamTask and ExamQuestion.
Background information
I have an Entity class called Exam
This class can contain one or more entities 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
can be of two types as shown below using JOINED
-
ExamTask
extendsExamObject
-
ExamQuestion
which expandsExamObject
and has a column namedquestionNumber
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;
...
source to share
By declaring the set to be of type TreeSet
and providing the constructor with a construct Comparator
, the inserted items will be sorted automatically.
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;
}
});
source to share
I believe your problem is that you are using the set in your essence. The set will not maintain order. When your relationship is loaded, the set does not guarantee the insertion order. Try using a list instead. The list will keep the insertion order.
@Entity
public class Exam {
@OneToMany(mappedBy = "exam" ...)
@OrderBy("id") //I need to order this by question number if its ExamQuestion
private List<ExamObject> objects;
...
}
Hope it helps.
source to share