Hibernate 是否可以统一由spring数据生成的findby查询

Hibernate 是否可以统一由spring数据生成的findby查询,hibernate,spring-data,spring-data-jpa,jpql,Hibernate,Spring Data,Spring Data Jpa,Jpql,我有这样一个实体类: @Entity @Table(name="app_user_role") public class AppUserRole implements Serializable { private static final long serialVersionUID = 1L; @EmbeddedId private AppUserRolePK id; //uni-directional many-to-one association to

我有这样一个实体类:

@Entity
@Table(name="app_user_role")
public class AppUserRole implements Serializable {

    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private AppUserRolePK id;

    //uni-directional many-to-one association to App
    @ManyToOne
    @JoinColumn(name="id_app", insertable=false, updatable=false)
    private App app;

    //uni-directional many-to-one association to Role
    @ManyToOne
    @JoinColumn(name="id_role", insertable=false, updatable=false)
    private Role role;

    //uni-directional many-to-one association to User
    @ManyToOne
    @JoinColumn(name="id_user", insertable=false, updatable=false)
    private User user;

}
然后,调用下一个方法:

List<AppUserRole> appUserRoles= appUserRoleRepository.findByAppAndUser(app, user);
它生成了多个分开的查询, 如何仅在一个查询中统一此查询

假设下一个方法仅生成一个查询:

AppUserRolePK appUserRolePK = new AppUserRolePK(app.getId(), role.getId(), user.getId() );
AppUserRole appUserRole1 = appUserRoleRepository.findOne(appUserRolePK);
生成的查询:

Hibernate: select appuserrol0_.id_app as id_app1_2_0_, appuserrol0_.id_role as id_role2_2_0_, appuserrol0_.id_user as id_user3_2_0_, appuserrol0_.state as state4_2_0_, app1_.id as id1_0_1_, app1_.app as app2_0_1_, app1_.descr as descr3_0_1_, role2_.id as id1_4_2_, role2_.id_app as id_app3_4_2_, role2_.role as role2_4_2_, app3_.id as id1_0_3_, app3_.app as app2_0_3_, app3_.descr as descr3_0_3_, user4_.id as id1_5_4_, user4_.mail as mail2_5_4_, user4_.password as password3_5_4_, user4_.username as username4_5_4_ from security.app_user_role appuserrol0_ left outer join security.app app1_ on appuserrol0_.id_app=app1_.id left outer join security.role role2_ on appuserrol0_.id_role=role2_.id left outer join security.app app3_ on role2_.id_app=app3_.id left outer join security.user user4_ on appuserrol0_.id_user=user4_.id where appuserrol0_.id_app=? and appuserrol0_.id_role=? and appuserrol0_.id_user=?

提前感谢

这是映射对象时的常规行为(加载了eager,默认情况下
@ManyToOne

对于示例中的第一个查询,将接收映射对象的标识符:

appuserrol0_.id_app as id_app1_2_, appuserrol0_.id_role as id_role2_2_, appuserrol0_.id_user as id_user3_2_,
如果在当前持久性上下文中还不可用,则以下查询将使用每个对象本身的值(满足映射的获取策略所需的值)来获取它们。如果它们已经存在于(第一级)缓存中,则不需要进行其他选择

如果要重写此行为,请自行编写HQL,也可以使用
@Query
注释在Spring数据JPA存储库中执行此操作:

@Query("FROM AppUserRole aur JOIN FETCH aur.app a JOIN FETCH aur.user u JOIN FETCH aur.role r WHERE a =:app AND u =:user")
Set<AppUserRole> findByAppAndUser(@Param("app") App app, @Param("user") User user);
@Query(“来自AppUserRole aur JOIN FETCH aur.app a JOIN FETCH aur.user u JOIN FETCH aur.role r,其中a=:app和u=:user”)
设置findByAppAndUser(@Param(“app”)app app、@Param(“user”)user);

请记住,当您将此查询与
joinfetch
语句一起使用时,您将失去延迟加载方法的所有优点。

谢谢,joinfetch就是答案。我一直在使用fetch模式研究一级缓存,但我没有找到示例,欢迎使用。基本上,只要当前持久性上下文/会话处于打开状态,一级缓存就会存储已查询的实体,请参见我前面评论中的链接。当一个实体在此缓存中可用并且再次被查找(通过identifer)时,无需再次访问数据库。我还纠正了代码片段中的一个小复制粘贴问题:)
@Query("FROM AppUserRole aur JOIN FETCH aur.app a JOIN FETCH aur.user u JOIN FETCH aur.role r WHERE a =:app AND u =:user")
Set<AppUserRole> findByAppAndUser(@Param("app") App app, @Param("user") User user);