java - JPA获取一对多

标签 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 session ,并按照@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);  

需要注意的一件事是,我尝试使用展开 session 中的 HQL。我将 DISTINCT 添加到查询中,并将结果转换器设置为 DISTINCT_ROOT_ENTITY,类似于上面的标准解决方案。这样做仍然创建了一个不同的 SQL 查询。

最佳答案

您需要一个ResultTransformer

试试下面的 HQL:

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

这等同于在条件查询中使用 CriteriaSpecification.DISTINCT_ROOT_ENTITY

关于java - JPA获取一对多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10131845/

相关文章:

java - Hibernate Spatial - 尝试加载 Oracle 几何时抛出 UnsupportedOperationException

hibernate - 外键的列数错误

java - Hibernate - ManyToMany 使用映射表之一的唯一属性

java - 使用Java从html中提取 anchor 标记

java - 如何在 hibernate 中使用外键和连接表以及单向进行一对一关联

java - 使用 JpaRepository : how to filter LocalDateTime based only on year, 月和日的 SQL 查询?

java - hibernate多对多防止子项删除

具有不同选择的 Spring Data JPA 投影

java - 无需安装即可分发 Java 8 JRE?

JavaFX:从运行时加载的模态获取数据