JPA取一对多

时间:2012-04-12 21:06:40

标签: java hibernate jpa

我有以下实体:事件和属性。事件可以具有许多属性。

我遇到的问题是,我似乎找不到在单个SQL查询中返回带有属性的事件的查询。我可以有数以百万计的事件需要迭代,我不想因为明显的性能原因而懒得加载它们。

我尝试在查询中使用fetch,但它会为每个属性返回一个事件。即如果一个事件有2个属性,它将返回2个事件,每个事件都有一个属性。

我想要的是一个有2个属性的事件。

SELECT e FROM Event e LEFT JOIN FETCH e.attributes

如果我添加DISTINCT它可以工作,但它会创建一个独特的SQL查询,这对大型数据集来说非常慢。

public class Event {
  @OneToMany(mappedBy = "event", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
  public Set<Attribute> getAttributes(){}
}

public class Attribute {
    @ManyToOne(cascade=CascadeType.ALL)
    @JoinColumn(name = "event_id", nullable = false)
    public Event getEvent() {
        return event;
    }
}

解决方案

我找不到JPA解决方案。相反,我将EntityManager打包到Hibernate会话并使用条件的结果转换器作为@milkplusvellocet建议。这将检索不同的根实体,而不会创建不同的SQL查询。

Session session = em.unwrap(Session.class);
Criteria criteria = session.createCriteria(Event.class);
criteria.setFetchMode("attributes", FetchMode.JOIN);

criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);  

有一点需要注意的是,我尝试在解包的会话中使用HQL。我将DISTINCT添加到查询中,并将结果转换器设置为DISTINCT_ROOT_ENTITY,类似于上面的条件解决方案。这样做仍然创建了一个独特的SQL查询。

1 个答案:

答案 0 :(得分:3)

您需要ResultTransformer

尝试以下HQL:

SELECT DISTINCT e FROM Event e LEFT JOIN FETCH e.attributes

这相当于在条件查询中使用CriteriaSpecification.DISTINCT_ROOT_ENTITY