Hibernate: выборка только списка связанных объектов - PullRequest
0 голосов
/ 05 декабря 2011

В данный момент я немного заблудился в лесу, пытаясь оптимизировать, как Hibernate получает свои данные из базы данных.Вот случай:

У меня есть класс Person, который имеет связь OneToMany с классом Address.Во время запроса с точки зрения приложения известно, что нам не понадобится экземпляр Person, но нам бы хотелось иметь список адресов этого человека.

Классы выглядят более /менее похоже на это (геттеры / сеттеры опущены):

@Entity
public class Person {
    @Id
    @GeneratedValue
    private Long id;
    @Column
    private String firstName;
    @Column
    private String lastName;
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name="address_id")
    private Set<Address> addresses = new HashSet<Address>();
//...
}

@Entity
public class Address {
    @Id
    @GeneratedValue
    private Long id;
    @Column
    private String city;
    @Column
    private String street;
//...
}

Теперь я хотел бы добиться запроса критериев (у меня есть все остальные части системы, уже использующие Criteria API, и я бы оченьочень похоже на то, чтобы оно было согласованным), которое будет возвращать адреса, принадлежащие данному человеку.

1 Ответ

1 голос
/ 05 декабря 2011

Критерии - это ограничивающий фактор: он позволяет выбрать только корневую сущность или скаляры. А поскольку у вас нет обратной связи (от адреса к человеку), это невозможно сделать простым способом с помощью критериев.

Я считаю HQL гораздо более гибким и гораздо более читабельным. Критерии полезны, когда запрос должен быть динамически составлен, но в этом случае использовать HQL-запрос просто:

select a from Person p inner join p.addresses a where p.id = :personId

Это на самом деле выполнимо в Criteria, но для этого нужен запрос, который менее эффективен и прост: что-то вроде

select a from Address a where a.id in (select a2.id from Person p inner join p.addresses a2 where p.id = :personId)

переведено в критерии.

Это было бы:

Criteria criteria = session.createCriteria(Address.class, "a");

DetachedCriteria dc = DetachedCriteria.forClass(Person.class, "p");
dc.createAlias("p.addresses", "a2");
dc.add(Restrictions.eq("p.id", personId);
dc.setProjection(Projections.property("a2.id"));

criteria.add(Subqueries.propertyIn("a.id", dc));

Как видите: менее читабелен, намного длиннее и менее эффективен.

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