【问题标题】:FetchMode Subselect not running on Set attributeFetchMode Subselect 未在 Set 属性上运行
【发布时间】:2020-09-08 16:14:20
【问题描述】:

我的班级有一个Set 集合属性,并标有@Fetch(value = FetchMode.SUBSELECT)。但它仍然使用不同的查询加载属性,而不是仅使用 subselect 加载属性

@Entity
@Table(name = "NPRO_USUARIOS")
public class User implements Serializable {
   //Method and atributes supressed
   @ManyToMany(cascade = { CascadeType.ALL })
   @JoinTable(name = "NPRO_USUARIOS_AREAS", joinColumns = @JoinColumn(name = "id_usuario"), inverseJoinColumns = @JoinColumn(name = "id_area"))
   @Fetch(value = FetchMode.SUBSELECT)
   private Set<Area> listAreas;
   // ...
}

这是日志:

Hibernate: select user0_.id_usuario as id_usuario1_22_0_, user0_.activo as activo2_22_0_, user0_.email_usuario as email_usuario3_22_0_, user0_.fecha_ultimo_acceso as fecha_ultimo_acces4_22_0_, user0_.matricula_usuario as matricula_usuario5_22_0_, user0_.nombre_usuario as nombre_usuario6_22_0_, user0_.observaciones as observaciones7_22_0_, user0_.usuario_modif as usuario_modif8_22_0_, user1_.id_usuario as id_usuario1_22_1_, user1_.activo as activo2_22_1_, user1_.email_usuario as email_usuario3_22_1_, user1_.fecha_ultimo_acceso as fecha_ultimo_acces4_22_1_, user1_.matricula_usuario as matricula_usuario5_22_1_, user1_.nombre_usuario as nombre_usuario6_22_1_, user1_.observaciones as observaciones7_22_1_, user1_.usuario_modif as usuario_modif8_22_1_ from npro_usuarios user0_ left outer join npro_usuarios user1_ on user0_.usuario_modif=user1_.id_usuario where user0_.id_usuario=?

Hibernate: select listareas0_.id_usuario as id_usuario1_23_0_, listareas0_.id_area as id_area2_23_0_, area1_.id_area as id_area1_5_1_, area1_.activo as activo2_5_1_, area1_.clase_doc_telesap as clase_doc_telesap3_5_1_, area1_.fecha_modif as fecha_modif4_5_1_, area1_.nombre_area as nombre_area5_5_1_, area1_.observaciones as observaciones6_5_1_, area1_.id_sociedad as id_sociedad8_5_1_, area1_.tipo_dato as tipo_dato7_5_1_, area1_.usuario_modif as usuario_modif9_5_1_ from npro_usuarios_areas listareas0_ inner join npro_maestro_areas area1_ on listareas0_.id_area=area1_.id_area where listareas0_.id_usuario=?

知道为什么不只执行一个查询吗?

【问题讨论】:

  • 我不是专家,这似乎是预期的行为。你可以看看solidsyntax.be/2013/10/17/fetching-collections-hibernate/…。
  • 不,正如您在链接中看到的,预期行为是使用子查询进行一次查询,而不是 n+1 次查询
  • 这是在说A SUBSELECT generates one query to load the Customers and one additional query to fetch all the Invoice collections. 还是我的理解有误?你的情况不完全是这样吗?
  • 是的,对不起,你说得对。我很困惑。谢谢

标签: java sql hibernate jpa


【解决方案1】:

因此,您对User 的主要查询是您将永远拥有的查询。当你使用SUBSELECT fetching 时,它会触发一个额外的查询。如果您使用的是SELECT,它将为您获取的每 N 个User 对象触发一个查询,其中 N 是批量大小。如果您只获取一个用户(看起来就是这种情况),您也可以使用SELECT,这会产生类似的查询。

不同之处在于,SELECT 查询将按所有者 ID 进行查询,而 SUBSELECT 查询会将原始查询嵌入到查询中以获取集合。根据原始查询的复杂程度,最好使用具有适当批量大小的SELECT,以避免再次执行复杂的查询部分。但必须根据具体情况考虑这些性能方面。

【讨论】:

    猜你喜欢
    • 2016-01-04
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-05
    相关资源
    最近更新 更多