FetchMode Subselect在Set属性上未运行

huangapple go评论81阅读模式
英文:

FetchMode Subselect not running on Set attribute

问题

@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=?

为什么不仅执行一个子查询而是执行多个不同的查询,有何想法吗?

英文:

My class has a Set collection attribute and it's marked with @Fetch(value = FetchMode.SUBSELECT). But it is still loading the attribute with different queries instead of just one with subselect

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

And this is the log :

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=?

Any idea why is not just executing one query?

答案1

得分: 0

所以针对“User”的主查询是您将始终拥有的查询。当您使用SUBSELECT提取时,它将触发一个额外的查询。如果您使用SELECT,它将为每个获取的N个“User”对象触发一个查询,其中N是批量大小。如果您只获取单个用户,就像目前的情况一样,您也可以使用SELECT,这将产生类似的查询。

区别在于,SELECT查询将根据所有者ID进行查询,而SUBSELECT查询将原始查询嵌入到用于提取集合的查询中。根据原始查询的复杂程度,最好使用适当的批量大小来避免再次执行复杂的查询部分。但是这些性能方面的问题必须根据实际情况进行考虑。

英文:

So your main query for User is the one that you will always have. When you use SUBSELECT fetching, it will trigger one additional query. If you were using SELECT, it would trigger one query for every N User objects that you fetched, where N is the batch size. If you fetch only a single user, as it seems to be the case, you could also use SELECT which would produce a similar query.

The difference is, a SELECT query will query by owner id whereas a SUBSELECT query, will embed the original query into the query to fetch the collection. Depending on how complex the original query is, it might be better to use SELECT with a proper batch size to avoid executing the complex query parts again. But these performance aspects have to be considered on a case by case basis.

huangapple
  • 本文由 发表于 2020年9月9日 00:14:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/63797788.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定