hibernate - Hibernate:如何强制对所有嵌套属性进行单个查询?
问题描述
***感谢@christian-beikov,此问题已更新为完整的模型和更集中的问题
如果我通过 Id 查询 Moose 实体,生成的查询将在单个查询中加入第一个 Mooseling(包括相关的 Gooseling),但第二个 Mooseling.Gooseling 将在第二个 SELECT 语句中查询。
从调试输出中可以清楚地看出,它确定 mooseling2.gooseling 是“被认为是循环的”。有没有办法覆盖它并强制它在一个查询中加载整个树?
我在 Moose 对象上尝试了 @NamedEntityGraph,但这并没有改变任何东西。
2021-02-18 15:20:29.423 DEBUG 7909 --- [ main] o.h.p.entity.AbstractEntityPersister : Static SQL for entity: com.fetchpackage.domain.entity.Moose
2021-02-18 15:20:29.423 DEBUG 7909 --- [ main] o.h.p.entity.AbstractEntityPersister : Version select: select moose_id from mooses where moose_id =?
2021-02-18 15:20:29.423 DEBUG 7909 --- [ main] o.h.p.entity.AbstractEntityPersister : Snapshot select: select moose_.moose_id, moose_.mooseling_1_id as mooselin3_37_, moose_.mooseling_2_id as mooselin4_37_, moose_.other_num as other_nu2_37_ from mooses moose_ where moose_.moose_id=?
2021-02-18 15:20:29.423 DEBUG 7909 --- [ main] o.h.p.entity.AbstractEntityPersister : Insert 0: insert into mooses (mooseling_1_id, mooseling_2_id, other_num, moose_id) values (?, ?, ?, ?)
2021-02-18 15:20:29.423 DEBUG 7909 --- [ main] o.h.p.entity.AbstractEntityPersister : Update 0: update mooses set mooseling_1_id=?, mooseling_2_id=?, other_num=? where moose_id=?
2021-02-18 15:20:29.423 DEBUG 7909 --- [ main] o.h.p.entity.AbstractEntityPersister : Delete 0: delete from mooses where moose_id=?
2021-02-18 15:20:29.423 DEBUG 7909 --- [ main] o.h.p.entity.AbstractEntityPersister : Identity insert: insert into mooses (mooseling_1_id, mooseling_2_id, other_num) values (?, ?, ?)
2021-02-18 15:20:29.423 DEBUG 7909 --- [ main] o.h.l.p.b.i.spaces.QuerySpacesImpl : Adding QuerySpace : uid = <gen:0> -> org.hibernate.loader.plan.build.internal.spaces.EntityQuerySpaceImpl@7ec9780b]
2021-02-18 15:20:29.423 DEBUG 7909 --- [ main] o.h.p.walking.spi.MetamodelGraphWalker : Visiting attribute path : mooseling1
2021-02-18 15:20:29.423 DEBUG 7909 --- [ main] o.h.l.p.b.i.spaces.QuerySpacesImpl : Adding QuerySpace : uid = <gen:1> -> org.hibernate.loader.plan.build.internal.spaces.EntityQuerySpaceImpl@7101fb1c]
2021-02-18 15:20:29.423 DEBUG 7909 --- [ main] o.h.p.walking.spi.MetamodelGraphWalker : Visiting attribute path : mooseling1.gooseling
2021-02-18 15:20:29.423 DEBUG 7909 --- [ main] o.h.l.p.b.i.spaces.QuerySpacesImpl : Adding QuerySpace : uid = <gen:2> -> org.hibernate.loader.plan.build.internal.spaces.EntityQuerySpaceImpl@4c974fe8]
2021-02-18 15:20:29.424 DEBUG 7909 --- [ main] o.h.p.walking.spi.MetamodelGraphWalker : Visiting attribute path : mooseling1.gooseling.gooseData
2021-02-18 15:20:29.424 DEBUG 7909 --- [ main] o.h.p.walking.spi.MetamodelGraphWalker : Visiting attribute path : mooseling2
2021-02-18 15:20:29.424 DEBUG 7909 --- [ main] o.h.l.p.b.i.spaces.QuerySpacesImpl : Adding QuerySpace : uid = <gen:3> -> org.hibernate.loader.plan.build.internal.spaces.EntityQuerySpaceImpl@3c88bef5]
2021-02-18 15:20:29.424 DEBUG 7909 --- [ main] o.h.p.walking.spi.MetamodelGraphWalker : Visiting attribute path : mooseling2.gooseling
2021-02-18 15:20:29.424 DEBUG 7909 --- [ main] o.h.p.walking.spi.MetamodelGraphWalker : Property path deemed to be circular : mooseling2.gooseling
2021-02-18 15:20:29.424 DEBUG 7909 --- [ main] o.h.p.walking.spi.MetamodelGraphWalker : Visiting attribute path : otherNum
2021-02-18 15:20:29.424 DEBUG 7909 --- [ main] lanBuildingAssociationVisitationStrategy : Building LoadPlan...
2021-02-18 15:20:29.424 DEBUG 7909 --- [ main] h.l.p.e.i.LoadQueryJoinAndFetchProcessor : processing queryspace <gen:0>
2021-02-18 15:20:29.425 DEBUG 7909 --- [ main] o.h.l.p.build.spi.LoadPlanTreePrinter : LoadPlan(entity=com.fetchpackage.domain.entity.Moose)
@NamedEntityGraph(
name = "moose-mooseling-gooseling-entity-graph",
attributeNodes = {
@NamedAttributeNode(value = "mooseling1", subgraph = "mooseling-gooseling-subgraph"),
@NamedAttributeNode(value = "mooseling2", subgraph = "mooseling-gooseling-subgraph"),
},
subgraphs = {
@NamedSubgraph(
name = "mooseling-gooseling-subgraph",
attributeNodes = {
@NamedAttributeNode("gooseling")
}
)
}
)
@Entity
@Table(name = "mooses")
public class Moose {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer mooseId;
@Column
@NotNull
private Integer otherNum;
@ManyToOne
@JoinColumn(name = "mooseling_1_id")
private Mooseling mooseling1;
@ManyToOne
@JoinColumn(name = "mooseling_2_id")
private Mooseling mooseling2;
}
@Entity
@Table(name = "mooselings")
public class Mooseling {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer mooselingId;
@ManyToOne
@JoinColumn(name = "gooseling_id")
private Gooseling gooseling;
}
@Entity
@Table(name = "gooselings")
public class Gooseling {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer gooselingId;
@Column
@NotNull
private Integer gooseData;
}
解决方案
我想这与循环有关,但是由于您没有共享整个模型,因此很难确定。从关系结构中获取对象图的问题在于,它可能具有无法使用 SQL 中的普通连接建模的循环。所以 Hibernate 必须在某个时候停止加入,并使用专用的 select 语句加载其余部分。
首先,不要使用 EAGER fetching。以后会咬你的。始终使用 LAZY 获取关联。然后,您可以在 HQL 查询中使用实体图或 join fetch 来仅连接您实际需要用于用例的关联。
推荐阅读
- scenebuilder - SceneBuilder 套件被 Gluon 魅力隐藏的依赖所削弱?
- javascript - 使用 Vue Multiselect 在选择/输入时调用 Axios
- javascript - 如何使用 NodeJS 获得“使用 Twitter 登录”
- c# - 向已运行的 WPF 进程发送消息
- c# - 使用 Entity Framework 6 从数据库查询中检索列表
- python - 在某些条件下检查数据框中是否存在值的有效方法
- apache-kafka - 从消费者开始的主题中获取最新值,然后正常继续
- python - 如何打印数字小于 9 和数字大于 10 的项目?
- r - 增加 R 中 metafor 包的森林图输出中的图大小
- python - 如何像 np.random.seed 一样为 pd.sample 制作种子?