【问题标题】:Why is this FetchType.LAZY being ignored and all entities are being fetched on the query?为什么这个 FetchType.LAZY 被忽略并且所有实体都在查询中被获取?
【发布时间】:2019-10-17 17:52:00
【问题描述】:

我正在使用带有 Hibernate 的 Spring Boot 2,并且我有一个名为 ItemCarga 的实体:

@ManyToMany(cascade = { CascadeType.DETACH }, fetch = FetchType.LAZY)
@JoinTable(name = "rel_transp_carga", joinColumns = { @JoinColumn(name = "fk_item_carga") }, inverseJoinColumns = { @JoinColumn(name = "fk_transportadora") })
@LazyCollection(LazyCollectionOption.TRUE)
private Set<Transportadora> transportadoras = new HashSet<Transportadora>();

Whey 在我的存储库中使用该实体进行查询,如下所示:

@Query("select e from ItemCarga e where e.cnpjCeramica = :cnpjCeramica and (e.dataInserido between :inicio and :fim) ")
List<ItemCarga> listarProdutosPorPeriodo(
        @Param("cnpjCeramica") String cnpjCeramica, 
        @Param("inicio") Date dataInicial, 
        @Param("fim") Date dataFinal, 
        Sort sort);

结果是一组带有transportadoras 属性的ItemCarga 实体及其所有项目。

它不应该是 null 或空吗?

由于我没有在我的选择中提及该属性,因此不应该被忽略吗?

【问题讨论】:

  • 你怎么知道所有的transportadoras 都被提取了?基本上,当您使用调试器查看集合时,它会懒惰地获取对象,如果您打印内容,也是如此。所以基本上当你开始看它时,集合就会开始填满。
  • 好点,我怎么知道它不是?我的意思是,如果我不做任何事情来获取,如何确认没有被获取?
  • 如果您查看集合,它将被提取,这就是懒惰的全部意义所在。懒惰意味着在需要时获取。不要看,不要尝试使用size()等。

标签: java spring set spring-data jpql


【解决方案1】:

您确实在查询中提到了该属性:select e from ItemCarga e。这意味着您正在获取整个 ItemCarga 实体。由于您将transportadoras 定义为fetch = FetchType.LAZY,因此会创建一个代理(不会从数据库中获取数据)。

如果您使用事务调用查询,您可以遍历集合,然后休眠将获取子实体(这通常会导致 n+1 选择问题)。如果您尝试在事务之外访问它,LazyInitializationException 将被抛出。

由于它只是休眠的提示,因此您可以确保Set 不会以两种方式被获取:

  1. 通过不查询它,例如:

    @Query("select e.field1, e.field2 from ItemCarga e ...")
    List<Object[]> listarProdutosPorPeriodo...
    

    缺点是你必须投射结果,

  2. 通过使用 dto 和查询映射。我就不详细描述了,更多可以找here

  3. 通过使用投影 - 与要获取的字段的 getter 和 setter 接口。更多详情here

【讨论】:

  • 如何不获取整个ItemCarga 实体?我的意思是,不应该加载 transportadoras 属性。
  • 你看我的回答了吗?它不是从数据库中获取的,只是创建了代理。
  • 我读过,但这不是正在发生的事情,这正是问题所在,它正在被提取。
  • @franzfull 好的,我明白了,抱歉,添加了一些可能的解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-04
  • 2013-04-13
  • 1970-01-01
  • 2012-06-04
  • 1970-01-01
相关资源
最近更新 更多