为什么Spring Data会进行过多查询?

时间:2018-12-21 00:06:27

标签: java spring hibernate spring-data-jpa

存储库有以下JPA方法:

@Query("select new com.example.sweater.domain.dto.MessageDto(" +
        "   m, " +
        "   count(ml), " +
        "   sum(case when ml = :user then 1 else 0 end) > 0" +
        ") " +
        "from Message m left join m.likes ml " +
        "group by m")
Page<MessageDto> findAll(Pageable pageable, @Param("user") User user);

问题:代替@Query注释中指定的单个查询,用于分别选择每个消息的查询仍在飞向数据库。

问题:为什么会发生这种情况以及如何与之抗争?

可以在github上查看整个代码

UPD1:查询日志:

Hibernate: select message0_.id as col_0_0_, count(user2_.id) as col_1_0_, sum(case when user2_.id=? then 1 else 0 end)>0 as col_2_0_ from message message0_ left outer join message_likes likes1_ on message0_.id=likes1_.message_id left outer join usr user2_ on likes1_.user_id=user2_.id group by message0_.id order by message0_.id desc limit ?
Hibernate: select message0_.id as id1_0_0_, message0_.user_id as user_id5_0_0_, message0_.filename as filename2_0_0_, message0_.tag as tag3_0_0_, message0_.text as text4_0_0_, user1_.id as id1_4_1_, user1_.activation_code as activati2_4_1_, user1_.active as active3_4_1_, user1_.email as email4_4_1_, user1_.password as password5_4_1_, user1_.username as username6_4_1_, roles2_.user_id as user_id1_2_2_, roles2_.roles as roles2_2_2_ from message message0_ left outer join usr user1_ on message0_.user_id=user1_.id left outer join user_role roles2_ on user1_.id=roles2_.user_id where message0_.id=?
Hibernate: select message0_.id as id1_0_0_, message0_.user_id as user_id5_0_0_, message0_.filename as filename2_0_0_, message0_.tag as tag3_0_0_, message0_.text as text4_0_0_, user1_.id as id1_4_1_, user1_.activation_code as activati2_4_1_, user1_.active as active3_4_1_, user1_.email as email4_4_1_, user1_.password as password5_4_1_, user1_.username as username6_4_1_, roles2_.user_id as user_id1_2_2_, roles2_.roles as roles2_2_2_ from message message0_ left outer join usr user1_ on message0_.user_id=user1_.id left outer join user_role roles2_ on user1_.id=roles2_.user_id where message0_.id=?
Hibernate: select message0_.id as id1_0_0_, message0_.user_id as user_id5_0_0_, message0_.filename as filename2_0_0_, message0_.tag as tag3_0_0_, message0_.text as text4_0_0_, user1_.id as id1_4_1_, user1_.activation_code as activati2_4_1_, user1_.active as active3_4_1_, user1_.email as email4_4_1_, user1_.password as password5_4_1_, user1_.username as username6_4_1_, roles2_.user_id as user_id1_2_2_, roles2_.roles as roles2_2_2_ from message message0_ left outer join usr user1_ on message0_.user_id=user1_.id left outer join user_role roles2_ on user1_.id=roles2_.user_id where message0_.id=?
Hibernate: select message0_.id as id1_0_0_, message0_.user_id as user_id5_0_0_, message0_.filename as filename2_0_0_, message0_.tag as tag3_0_0_, message0_.text as text4_0_0_, user1_.id as id1_4_1_, user1_.activation_code as activati2_4_1_, user1_.active as active3_4_1_, user1_.email as email4_4_1_, user1_.password as password5_4_1_, user1_.username as username6_4_1_, roles2_.user_id as user_id1_2_2_, roles2_.roles as roles2_2_2_ from message message0_ left outer join usr user1_ on message0_.user_id=user1_.id left outer join user_role roles2_ on user1_.id=roles2_.user_id where message0_.id=?
Hibernate: select message0_.id as id1_0_0_, message0_.user_id as user_id5_0_0_, message0_.filename as filename2_0_0_, message0_.tag as tag3_0_0_, message0_.text as text4_0_0_, user1_.id as id1_4_1_, user1_.activation_code as activati2_4_1_, user1_.active as active3_4_1_, user1_.email as email4_4_1_, user1_.password as password5_4_1_, user1_.username as username6_4_1_, roles2_.user_id as user_id1_2_2_, roles2_.roles as roles2_2_2_ from message message0_ left outer join usr user1_ on message0_.user_id=user1_.id left outer join user_role roles2_ on user1_.id=roles2_.user_id where message0_.id=?
Hibernate: select message0_.id as id1_0_0_, message0_.user_id as user_id5_0_0_, message0_.filename as filename2_0_0_, message0_.tag as tag3_0_0_, message0_.text as text4_0_0_, user1_.id as id1_4_1_, user1_.activation_code as activati2_4_1_, user1_.active as active3_4_1_, user1_.email as email4_4_1_, user1_.password as password5_4_1_, user1_.username as username6_4_1_, roles2_.user_id as user_id1_2_2_, roles2_.roles as roles2_2_2_ from message message0_ left outer join usr user1_ on message0_.user_id=user1_.id left outer join user_role roles2_ on user1_.id=roles2_.user_id where message0_.id=?
Hibernate: select message0_.id as id1_0_0_, message0_.user_id as user_id5_0_0_, message0_.filename as filename2_0_0_, message0_.tag as tag3_0_0_, message0_.text as text4_0_0_, user1_.id as id1_4_1_, user1_.activation_code as activati2_4_1_, user1_.active as active3_4_1_, user1_.email as email4_4_1_, user1_.password as password5_4_1_, user1_.username as username6_4_1_, roles2_.user_id as user_id1_2_2_, roles2_.roles as roles2_2_2_ from message message0_ left outer join usr user1_ on message0_.user_id=user1_.id left outer join user_role roles2_ on user1_.id=roles2_.user_id where message0_.id=?
Hibernate: select message0_.id as id1_0_0_, message0_.user_id as user_id5_0_0_, message0_.filename as filename2_0_0_, message0_.tag as tag3_0_0_, message0_.text as text4_0_0_, user1_.id as id1_4_1_, user1_.activation_code as activati2_4_1_, user1_.active as active3_4_1_, user1_.email as email4_4_1_, user1_.password as password5_4_1_, user1_.username as username6_4_1_, roles2_.user_id as user_id1_2_2_, roles2_.roles as roles2_2_2_ from message message0_ left outer join usr user1_ on message0_.user_id=user1_.id left outer join user_role roles2_ on user1_.id=roles2_.user_id where message0_.id=?
Hibernate: select message0_.id as id1_0_0_, message0_.user_id as user_id5_0_0_, message0_.filename as filename2_0_0_, message0_.tag as tag3_0_0_, message0_.text as text4_0_0_, user1_.id as id1_4_1_, user1_.activation_code as activati2_4_1_, user1_.active as active3_4_1_, user1_.email as email4_4_1_, user1_.password as password5_4_1_, user1_.username as username6_4_1_, roles2_.user_id as user_id1_2_2_, roles2_.roles as roles2_2_2_ from message message0_ left outer join usr user1_ on message0_.user_id=user1_.id left outer join user_role roles2_ on user1_.id=roles2_.user_id where message0_.id=?
Hibernate: select message0_.id as id1_0_0_, message0_.user_id as user_id5_0_0_, message0_.filename as filename2_0_0_, message0_.tag as tag3_0_0_, message0_.text as text4_0_0_, user1_.id as id1_4_1_, user1_.activation_code as activati2_4_1_, user1_.active as active3_4_1_, user1_.email as email4_4_1_, user1_.password as password5_4_1_, user1_.username as username6_4_1_, roles2_.user_id as user_id1_2_2_, roles2_.roles as roles2_2_2_ from message message0_ left outer join usr user1_ on message0_.user_id=user1_.id left outer join user_role roles2_ on user1_.id=roles2_.user_id where message0_.id=?
Hibernate: select count(message0_.id) as col_0_0_ from message message0_ left outer join message_likes likes1_ on message0_.id=likes1_.message_id left outer join usr user2_ on likes1_.user_id=user2_.id group by message0_.id

UPD2:仍然注意到,当我尝试将Message传递给(m,...)时,根据我的需要,不是传递m而是传递消息的对象,并且消息的ID。也许这个休眠状态会为每条消息进入数据库?

1 个答案:

答案 0 :(得分:0)

使用JOIN FETCH并删除所有EAGER。

这是n + 1个JPA / JPQL问题的经典示例。