Hibernate:仅获取关联实体列表

时间:2011-12-04 21:25:57

标签: java hibernate

此时我有点迷失在树林中,试图优化Hibernate如何从数据库中获取数据。情况就是这样:

我有一个Person类,它与Address类有一个OneToMany关联。在查询时,从应用程序的角度来看,我们不需要Person实例,但我们希望获得该Person的地址列表。

这些类看起来更像/更少(省略了getters / setters):

@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 个答案:

答案 0 :(得分:1)

标准是限制因素:它只允许选择根实体或标量。而且由于你没有反向关联(从地址到人),因此不可能用Criteria以简单的方式进行。

我发现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));

如您所见:可读性更低,时间更长,效率更低。