英文:
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 = "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;
// ...
}
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论