首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用JPA Criteria API,您是否可以执行一个fetch join,只产生一个join?

使用JPA Criteria API,您是否可以执行一个fetch join,只产生一个join?
EN

Stack Overflow用户
提问于 2013-06-26 04:13:08
回答 2查看 55.9K关注 0票数 32

使用JPA 2.0。似乎在默认情况下(没有显式获取),@OneToOne(fetch = FetchType.EAGER)字段是在1+N个查询中获取的,其中N是包含定义与不同相关实体的关系的实体的结果数。使用Criteria API,我可能会尝试避免这种情况,如下所示:

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<MyEntity> query = builder.createQuery(MyEntity.class);
Root<MyEntity> root = query.from(MyEntity.class);
Join<MyEntity, RelatedEntity> join = root.join("relatedEntity");
root.fetch("relatedEntity");
query.select(root).where(builder.equals(join.get("id"), 3));

理想情况下,上述内容应等同于以下内容:

SELECT m FROM MyEntity m JOIN FETCH myEntity.relatedEntity r WHERE r.id = 3

但是,条件查询会导致根表不必要地连接到相关实体表两次;一次用于fetch,一次用于where谓词。生成的SQL如下所示:

SELECT myentity.id, myentity.attribute, relatedentity2.id, relatedentity2.attribute 
FROM my_entity myentity 
INNER JOIN related_entity relatedentity1 ON myentity.related_id = relatedentity1.id 
INNER JOIN related_entity relatedentity2 ON myentity.related_id = relatedentity2.id 
WHERE relatedentity1.id = 3

可惜,如果我只做fetch,那么我就没有表达式可以在where子句中使用。

我是否遗漏了什么,或者这是Criteria API的一个限制?如果是后者,那么在JPA 2.1中是否已对此进行了补救,或者是否有任何特定于供应商的增强?

否则,放弃编译时类型检查似乎更好(我意识到我的示例没有使用元模型),而使用动态JPQL TypedQueries。

EN

回答 2

Stack Overflow用户

发布于 2017-03-24 02:53:45

从JPA 2.1开始,您可以使用动态实体图来实现这一点。移除fetch并指定实体图,如下所示:

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<MyEntity> query = builder.createQuery(MyEntity.class);
Root<MyEntity> root = query.from(MyEntity.class);
Join<MyEntity, RelatedEntity> join = root.join("relatedEntity");
query.select(root).where(builder.equal(join.get("id"), 3));
EntityGraph<MyEntity> fetchGraph = entityManager.createEntityGraph(MyEntity.class);
fetchGraph.addSubgraph("relatedEntity");
entityManager.createQuery(query).setHint("javax.persistence.loadgraph", fetchGraph);
票数 11
EN

Stack Overflow用户

发布于 2015-04-27 21:50:06

在EclipseLink上使用root.fetch()将创建一个带有INNER JOIN的SQL,因为它有3种类型,缺省值是INNER。

INNER,  LEFT,  RIGHT;

建议使用CreateQuery。

TypedQuery<T> typedQuery = entityManager.createQuery(query);

编辑:您可以像这样将根转换为From:

From<?, ?> join = (From<?, ?>) root.fetch("relatedEntity");
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17306655

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档