Hibernate AliasToBean с коллекцией - PullRequest
       4

Hibernate AliasToBean с коллекцией

4 голосов
/ 09 сентября 2011

У меня двунаправленное отношение «один ко многим», определенное между родительским и дочерним классами. Я пытаюсь выполнить запрос, чтобы я мог вернуть один родительский элемент и подмножество его дочерних элементов в компоненте.

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
}

Результат, на который я рассчитываю:

public class ParentChildWrapper {
    private Parent parent;
    private Collection<Child> children; // subset of children
}

Я бы хотел отфильтровать по идентификатору родителя и столбцу возраста ребенка. Я пробовал несколько комбинаций запросов, чтобы получить желаемый результат.

Следующее близко, но не группирует дочерние элементы в коллекции в компоненте ParentChildWrapper, который я определил. В результате я получаю список объектов с 1 экземпляром на каждого ребенка, который соответствует возрастному фильтру:

Query q = session.createQuery(
    "SELECT p, c " +
    "FROM Parent p " +
    "INNER JOIN p.children c " +
    "WHERE p.id = :id " +
    "AND c.age = :age"
);

Я также пытался сгруппировать по родителям, чтобы попытаться объединить всех детей в коллекцию, также безрезультатно.

Очевидно, я мог бы разделить это на два отдельных запроса, чтобы выбрать родителя, а затем выбрать нужных мне детей. Но такое чувство, что это должно быть довольно распространенным вариантом использования. Возможно, я не думаю в спящем-esque способе.

1 Ответ

4 голосов
/ 09 сентября 2011

Только не используйте какой-либо преобразователь и кодируйте цикл самостоятельно:

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);

Это составляет 8 строк тривиального кода вместо 1, но позволяет избежать вызовов отражений и, таким образом, позволяет безопасно выполнять рефакторинг.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...