使用 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
然而,条件查询会导致根表不必要地两次连接到相关实体表;一次用于获取,一次用于 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。