java fetch_Java Hibernate条件使用FetchType.EAGER多次返回子级

小编典典

如果我正确理解你的配置,这实际上是预期的行为。

你Order在任何结果中都得到相同的实例,但是由于你现在正在使用进行联接OrderTransaction,因此它必须返回与常规sql联接将返回的结果相同的结果量

所以实际上它应该出现多次。这是由作者(是Gavin King)自己解释得非常好这里:它既解释了为什么,以及如何仍然得到不同的结果

在Hibernate FAQ中也提到过:

Hibernate不会为启用了集合的外部联接获取的查询返回不同的结果(即使我使用了distinct关键字)?首先,你需要了解SQL以及OUTER JOIN在SQL中的工作方式。如果你不完全理解并理解SQL中的外部联接,请不要继续阅读此FAQ项,而请查阅SQL手册或教程。否则,你将无法理解以下解释,并且会在Hibernate论坛上抱怨此行为。

可能返回相同Order对象的重复引用的典型示例:

List result = session.createCriteria(Order.class)

.setFetchMode("lineItems", FetchMode.JOIN)

.list();

...

List result = session.createCriteria(Order.class)

.list();

List result = session.createQuery("select o from Order o left join fetch o.lineItems").list();

所有这些示例都产生相同的SQL语句:

SELECT o.*, l.* from ORDER o LEFT OUTER JOIN LINE_ITEMS l ON o.ID = l.ORDER_ID

想知道为什么有重复吗?查看SQL结果集,Hibernate不会在外部联接结果的左侧隐藏这些重复项,而是返回驱动表的所有重复项。如果数据库中有5个订单,并且每个订单有3个订单项,则结果集将为15行。这些查询的Java结果列表将包含15个元素,所有元素均为Order类型。Hibernate将仅创建5个Order实例,但SQL结果集的重复项将保留为这5个实例的重复引用。如果你不明白这最后一句话,则需要阅读Java以及Java堆上的实例与对该实例的引用之间的区别。

(为什么要使用左外部联接?如果你有没有订单项的其他订单,则结果集将是16行,右侧填充NULL,而订单项数据用于其他订单。即使你想要订单,即使他们没有订单项,对吗?如果没有,请在你的HQL中使用内部联接提取)。

默认情况下,Hibernate不会过滤掉这些重复的引用。有些人(不是你)实际上想要这个。如何过滤掉它们?

像这样:

Collection result = new LinkedHashSet( session.create*(...).list() );

2020-03-09

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FetchType.LAZY是Hibernate中的一种加载策略。当使用懒加载策略时,加载一个实体时,定义为懒加载的属性并不会立即从数据库中加载,而是在需要访问这些属性时才会去数据库中查询加载。 这种策略的好处是可以减少不必要的数据库查询,提高性能。比如在一个用户类中,用户的地址属性在大多数情况下并不需要立即显示出来,只有在需要查看用户资料时才会去查询数据库加载地址信息。而用户名属性则需要在用户登录时立即显示出来,因此需要使用急加载策略。 在Hibernate中,可以通过在实体类的属性上使用注解来设置延迟检索策略。例如,可以使用@OneToMany注解来设置一对多关系中的延迟加载策略。通过设置fetch属性为FetchType.LAZY,可以显式地指定该属性的延迟加载策略。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [hibernatefetch=FetchType.LAZY 懒加载失败处理方法](https://download.csdn.net/download/weixin_38682242/12771863)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [HibernateFetchType.LAZY和FetchType.EAGER什么区别?](https://blog.csdn.net/B_evan/article/details/53868520)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [孙卫琴的《精通JPA与Hibernate》的读书笔记:FetchType.LAZY延迟检索策略](https://blog.csdn.net/csdnuserlala/article/details/116403315)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值