Order by both Parent and then Child using JPA
Is it possible to order a collection of parent objects by both a parent's property and a child's property?
Let's say I have an Entity class that has this bit of code:
@OrderBy("age")
public List<Father> getFathers() {
return fathers;
}
The Father Entity has an age property which we want to order by ascending age (as shown above).
A Father can have a Child. A Child would also have an age property. I would like getFathers()
to return a Fathers list such that they are ordered by the Fathers' age and then subsequently the Child's age ascending.
If I keep the code above as is, the Fathers would be ordered by their own age correctly but a Father (aged 30) with a 10 year old Child could come before a Father (also aged 30) with a 5 year old Child.
I tried doing something like this:
@OrderBy("age, child.age")
public List<Father> getFathers() {
return fathers;
}
But I would get the following exception:
org.hibernate.AnnotationException: property from @OrderBy clause not found: Father.chil开发者_如何学God.age
Edit: Sorry, let me clarify with a bit more code. The getFathers()
is not in the Child entity but in another entity. Let's call it Village:
@Entity
public class Village {
...
@OneToMany(mappedBy = "village",
targetEntity = Father.class)
@OrderBy("age")
public List<Father> getFathers() {
return fathers;
}
}
So let's say there is a Village and you can obtain the Fathers that live in this Village. For this example's sake, let's say that a Father for some odd Village rule can only have one child each.
So Father would look something like this:
@Entity
public class Father {
private Child child;
...
@OneToOne(mappedBy = "father")
public Child getChild() {
return child;
}
public void setChild(Child child) {
this.child = child;
}
}
So now in the original Village class, I want getFathers()
to return all the fathers in order of age, plus, if there are any fathers with the same age, I want them to be then ordered by the age of their child.
Edit 2: I've also found that I can get the effect of what I want however it can't be the most elegant way of doing it:
session.createFilter(village.getFathers(), "order by child.age");
It seems like you are missing two-way mapping. You should also map Child
in Father
.
By the way, there should be one-to-many relationship between Father
and Child
, traditionally speaking. Which means in Father
class there should be a List<Child> children;
property, and not the other way around.
[EDIT]
No, you can't do like that. Why? Because when you define your @OrderBy("age, child.age")
, the whole of it, child.age
, would be considered as a property. It will be treated as a String
. Hence, indeed, you don't have any property name child.age
in Father
class. I hope you are getting my point. So, the Filter
solution, you came up with, is a good way to go.
精彩评论