@LazyCollection(LazyCollectionOption.FALSE) 和 @OneToMany(fetch = FetchType.EAGER) 之间的区别

Posted

技术标签:

【中文标题】@LazyCollection(LazyCollectionOption.FALSE) 和 @OneToMany(fetch = FetchType.EAGER) 之间的区别【英文标题】:Difference between @LazyCollection(LazyCollectionOption.FALSE) and @OneToMany(fetch = FetchType.EAGER) 【发布时间】:2014-11-17 18:11:14 【问题描述】:

我对“延迟加载”有一个疑问。 使用@LazyCollection(LazyCollectionOption.FALSE)@OneToMany(fetch = FetchType.EAGER)有什么区别?

在我的应用程序中,我使用了两个列表,但如果我以这种格式使用:

@OneToMany(mappedBy = "consultaSQL", orphanRemoval = true, fetch = FetchType.EAGER,
        cascade = CascadeType.ALL)
private List<ParametroSQL> parametros;


@OneToMany(mappedBy = "consulta", orphanRemoval = true, fetch = FetchType.EAGER,
        cascade = CascadeType.ALL)
private List<Contato> contatos;

我有这个错误:

原因:org.hibernate.loader.MultipleBagFetchException: 不能同时获取多个包

我知道这是因为 Hibernate 不允许我同时加载两个列表。但如果我使用这种格式:

@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy = "consultaSQL", orphanRemoval = true,
        cascade = CascadeType.ALL)
private List<ParametroSQL> parametros;

@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy = "consulta", orphanRemoval = true,
        cascade = CascadeType.ALL)
private List<Contato> contatos;

效果很好。

对不起我的英语 谢谢

【问题讨论】:

【参考方案1】:

正如本文所建议的那样:https://***.com/a/5865605/5619076 通过 Set 更改列表应该可以解决 MultipleBagFetchException。 这解决了我的问题。

【讨论】:

这个post 解释了为什么更改为 Set 不是正确的解决方案。【参考方案2】:

我想我也遇到了同样的问题......

尝试所有系列...

 @Fetch(FetchMode.SUBSELECT)

它应该消除错误

【讨论】:

【参考方案3】:

注解之间的根本区别在于@OneToMany 及其参数(例如fetch = FetchType.EAGER)是纯JPA。它可以与任何 JPA 提供程序一起使用,例如 Hibernate 或 EclipseLink。

另一方面,@LazyCollection 是特定于 Hibernate 的,显然只有在使用 Hibernate 时才有效。

如果可能,请尽量遵守 JPA 规范。通过这样做,您应该能够轻松切换提供商(至少在理论上)。

至于你真正的问题,是不是你正在使用不支持 JPA 2.0 的 Hibernate 版本,正如this 回答所暗示的那样?

【讨论】:

OP描述的FetchType.EAGER的问题还在Hibernate 5.2版本中。

以上是关于@LazyCollection(LazyCollectionOption.FALSE) 和 @OneToMany(fetch = FetchType.EAGER) 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

JPQL 用于单向 OneToMany

我可以在@OneToMany 上使用@JoinColumn 吗?