在 Hibernate 中,
@ManyToOne
关系几乎不会导致任何问题,因为默认获取类型是 EAGER
。
然而,我们在
@OnetoMany
最后遇到了关键问题。当我们尝试获取集合时,
LazyInitializationException: could not initialize proxy
被抛出,因为对于
one-to-many,默认的获取类型是
LAZY
。
在这种情况下,我们可以设置:
@LazyCollection(LazyCollectionOption.FALSE)
,虽然解决了问题,但是当有一堆记录时,它会显着影响性能。
fetch
模式:左连接但会抛出
org.hibernate.HibernateException: cannot simultaneously fetch multiple bags
据我所知,Hibernate 建议了几种机制来克服这个问题:
选项1:
指定
@IndexColumn
而不是制作 LazyCollectionOption.FALSE
。因此,确定了以下也会影响性能的行为:
使用各个实体的主键创建临时表(
@OnetoMany
)。因此,当存在许多一对多关系时,将为每个关系创建临时表。
选项2:
将集合的数据类型从
List
更改为 Set
。这会导致 Struts 2 前端出现问题,因为 Set
是基于索引的集合,因为我们需要以迭代方式动态添加记录。
为了克服这个问题,我们将利用 DTO 来捕获 UI 输入。通过在 DTO 中创建集合类型
List
,在 domain中创建
Set
,并通过汇编器,我们将进行从 List
→ Set
(DTO → 域)所需的转换,反之亦然。
选项 2 中提到的解决方案是否可行?如果没有,请提供建议和反馈。
根据我的经验,通常只有一两个地方需要急切初始化(例如:在“记录详细信息”视图中)。对于这种情况,除了一些需要 eager 的地方之外,总是存在惰性的情况,有一个名为 “Fetch profile” 的 Hibernate 功能。这是一个相对较新的功能,不太为人所知,但它非常强大,在这种情况下可能会有所帮助。
不幸的是,这还没有在 JPA 中,这意味着您需要在干净的 JPA 代码中添加一些专有的 Hibernate 部分,但在我看来,这是一个很低的价格。