问题
I have a bi-directional one-to-many relationship defined between Parent and Child classes. I'm looking to execute a query such that I can return a single parent, and a subset of its children in a bean.
public class Parent {
private int id;
private Set<Child> children = new HashSet<Child>(0);
// other fields + getters and setters
}
public class Child {
private Parent parent;
private int age;
// other fields + getters and setters
}
The output I'm looking to achieve is:
public class ParentChildWrapper {
private Parent parent;
private Collection<Child> children; // subset of children
}
I'd like to filter on the parent's id and the child's age column. I've tried a number of query combinations in order to get the desired output.
The following is close, but doesn't group the children in a collection in the ParentChildWrapper bean I've defined. The result I get is a list of objects, with 1 instance per child that matches the age filter:
Query q = session.createQuery(
"SELECT p, c " +
"FROM Parent p " +
"INNER JOIN p.children c " +
"WHERE p.id = :id " +
"AND c.age = :age"
);
I've also tried to group by the parent in order to try and aggregate all the children into a collection, also to no avail.
Obviously I could separate this into two separate queries in order to select the parent, and then select the children that I want. But it feels like this should be a fairly common use case. Perhaps I'm not thinking in a hibernate-esque way.
回答1:
Just don't use any transformer and code the loop yourself:
List<Object[]> rows = query.list();
Parent parent = null;
List<Child> children = new ArrayList<Child>(rows.size());
for (Object[] row : rows) {
parent = (Parent) row[0];
children.add((Child) row[1]);
}
ParentChildWrapper result = new ParentChildWrapper(parent, children);
This makes 8 lines of trivial code instead of 1, but avoids reflection calls, and thus allows safe refactoring.
来源:https://stackoverflow.com/questions/7363152/hibernate-aliastobean-with-collection