spring-data-jpa - 使用 JPQL/EntitGraph 加载子实体不适用于 EclipseLink 和 spring 数据
问题描述
我正在尝试使用 EntityGraphs 或 JPQL 创建 1 个选择,而不是许多小(子)选择。但是,在额外的选择中加载了子实体。例子:
@NamedEntityGraph( name = "All",
attributeNodes = {
@NamedAttributeNode( value = "bars", subgraph = "subgraph.foobars") },
subgraphs = {
@NamedSubgraph( name = "subgraph.foobars",
attributeNodes = {
@NamedAttributeNode(value = "fooBars", subgraph = "subgraph.foobar"),
@NamedAttributeNode( "mqttEndpoints" ) } ),
@NamedSubgraph( name = "subgraph.foobar",
attributeNodes = {
@NamedAttributeNode( "name" ) } ) })
public class Foo {
@OneToMany( fetch = FetchType.LAZY )
private Set<Bar> bars = Sets.newHashSet();
}
public class Bar {
@OneToMany( fetch = FetchType.LAZY )
private Set<FooBar> fooBars = Sets.newHashSet();
}
public class FooBar {
String name;
}
@EntityGraph( value = "All", type = EntityGraph.EntityGraphType.FETCH )
Optional<Foo> findById( String id);
@Query( "SELECT DISTINCT f FROM foo f"
+ " LEFT JOIN FETCH f.bar bars "
+ " LEFT JOIN FETCH bar.fooBars foobars "
+ " WHERE t.id =:id " )
Optional<Foo> readById( String id);
日志
SELECT ...
FROM foo t1
LEFT OUTER JOIN bars t0 ON (t0.bar_id = t1.id)
SELECT name
FROM foobar
WHERE ...
如果我使用查询提示,那么它可以与子选择一起使用,那么出了什么问题? https://www.eclipse.org/eclipselink/documentation/2.5/jpa/extensions/q_left-join-fetch.htm
使用休眠,这很好用。
解决方案
您会注意到 EclipseLink 总是对任何关系映射进行额外查询,除非您指定 fetchJoin 注释(或查询提示,或使用定制器修改映射)告诉它要做什么,这与关系是否急切或懒惰无关获取。另一方面,Hibernate 解释所有使用 join 的渴望访问。没有必要争论哪个更好 - 它们是情境性的,有充分的理由将任何一种解决方案作为通用解决方案。
这意味着,如果您想要与 EclipseLink 即时连接,您必须做的不仅仅是指出需要急切地获取关系,并包括在查询提示中。如果您要使用提取图来优化事物,那么查看其他提取类型(例如批量提取)可能会有所帮助。额外的查询/语句对性能并不总是坏事,尤其是随着对象图的增长。数据库将被迫返回 N*M 重复的 Foo 数据行,结果中的每个 Bar 和 FooBar 组合一个。根据数据大小,在某个点上,让子项进入单独的查询会更有效。
推荐阅读
- android - 为 Android 12 (FLAG_IMMUTABLE) 构建 React Native 应用程序的 PendingIntent 问题
- javascript - 在 Javascript 中创建一个名为 zip() 的函数
- c - 如何从 void 指针获取 switch 语句的可用 int?
- python - os.open Windows 文件权限模式
- python - 是否可以使用 python 在纯 Java 中制作本机?
- python - df.value.counts() 不显示数据集中出现的次数
- c# - 如何从 IL 指令生成 C# 代码
- mysql - 如何组合来自两个不同表的公共列内的值?
- javascript - 在 React Native 中实现步进栏动画的更好方法?
- arraylist - 如何在charp中映射两个类属性