Java QueryDSL fetchJoin不提取数据

Java QueryDSL fetchJoin不提取数据,java,hibernate,spring-data-jpa,querydsl,Java,Hibernate,Spring Data Jpa,Querydsl,我面对这个问题: 假设我有3个这样的实体: 实体A: long id String someField // No bidirectional linkage to B entity via hibernate 实体B: long id String someBField @ManyToOne(optional = false, fetch = FetchType.LAZY) @JoinColumn(name="b_id") A entityA @ManyToOn

我面对这个问题:

假设我有3个这样的实体:

实体A:

long id

String someField

// No bidirectional linkage to B entity via hibernate
实体B:

long id

String someBField

@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name="b_id")
A entityA

@ManyToOne(optional = true, fetch = FetchType.LAZY)
@JoinColumn(name="b_id")
C entityC;   
实体C:

long id

String someCField

// No bidirectional linkage to B entity via hibernate
现在,我们的目标是(为了简单起见,有一些排序和筛选,但这并不影响我的问题)返回所有B记录,每个记录都有A和C记录

所以我做了类似的事情(我习惯于使用SpringDataJPA(左)连接获取属性,以避免延迟按需加载,以防止向数据库中触发无用的查询,我想在QueryDSL中做完全相同的事情)

例如,当我调用一个项目时,QueryDSL返回了什么

b、 getC()或b.getA(),我正在向数据库触发另一个查询,这是我首先要避免的事情


我做错了什么?

我认为,连接条件的定义不合适

希望我已经用UserEntity角色重新创建了所描述的星座:

@Entity
@Table(name = "t_user")
public class UserEntity {

    @Id
    @Column(name = "id")
    private Integer id;
    @Column(name = "name") 

    // ..
}

@Entity
@Table(name = "t_user_role")
public class UserRoleEntity {
    @Id
    @Column(name = "id")
    private Integer id;
    @ManyToOne
    @JoinColumn(name = "user_id")
    private UserEntity user;
    @ManyToOne
    @JoinColumn(name = "role_id")
    private RoleEntity role;

    // ..
}

@Entity
@Table(name = "t_role")
public class RoleEntity {
    @Id
    @Column(name = "id")
    private Integer id;
    @Column(name = "name")
    private String name;

    // ..
}
询问

List<UserRoleEntity> findAll() {
    JPAQuery<UserRoleEntity> query = new JPAQuery<>(entityManager);

    return query.select(QUserRoleEntity.userRoleEntity)
            .from(QUserRoleEntity.userRoleEntity)
            .innerJoin(QUserRoleEntity.userRoleEntity.user).fetchJoin()
            .innerJoin(QUserRoleEntity.userRoleEntity.role).fetchJoin()
            .fetch();

}

我应该重新阅读JPA规范来确定,但我认为只有当连接的实体也投影在元组中时,fetch连接才适用。否则,这可能是一个休眠错误?最后,Hibernate负责生成SQL。我不知道生成了什么类型的HQL查询,但Hibernate正确地支持这一点。你能分享生成的HQL查询吗?@ChristianBeikov我不确定是否生成了HQL Being,我已经在文章末尾编写了生成的“原始”SQL,在“选择”部分应该有更多的列(c.someCField,a.someField,…),但它不是。那么调用getA()或getC()将产生另一个query@Jan-Willemgmeyling你确定这些选择吗?当我在寻找答案时,我没有看到这样的答案。每个人都只选择了应该提取的实体。我一直在研究doc,没有什么可以回答我的问题。@Jan Willemgmeyling,如下面的答案中所述,将join更改为“Hibernate-like”,因为fetch-join工作。在我的情况下,加入“类似SQL”将导致fetch加入不起作用。谢谢你的时间,谢谢你的回答。将联接类型从“Hibernate-like”(因此不指定联接字段)更改将导致fetchjoin立即工作。谢谢你的回答。
@Entity
@Table(name = "t_user")
public class UserEntity {

    @Id
    @Column(name = "id")
    private Integer id;
    @Column(name = "name") 

    // ..
}

@Entity
@Table(name = "t_user_role")
public class UserRoleEntity {
    @Id
    @Column(name = "id")
    private Integer id;
    @ManyToOne
    @JoinColumn(name = "user_id")
    private UserEntity user;
    @ManyToOne
    @JoinColumn(name = "role_id")
    private RoleEntity role;

    // ..
}

@Entity
@Table(name = "t_role")
public class RoleEntity {
    @Id
    @Column(name = "id")
    private Integer id;
    @Column(name = "name")
    private String name;

    // ..
}
List<UserRoleEntity> findAll() {
    JPAQuery<UserRoleEntity> query = new JPAQuery<>(entityManager);

    return query.select(QUserRoleEntity.userRoleEntity)
            .from(QUserRoleEntity.userRoleEntity)
            .innerJoin(QUserRoleEntity.userRoleEntity.user).fetchJoin()
            .innerJoin(QUserRoleEntity.userRoleEntity.role).fetchJoin()
            .fetch();

}
    select 
        userroleen0_.id as id1_5_0_, 
        userentity1_.id as id1_4_1_, 
        roleentity2_.id as id1_2_2_, 
        userroleen0_.role_id as role_id2_5_0_, 
        userroleen0_.user_id as user_id3_5_0_, 
        userentity1_.name as name2_4_1_, 
        roleentity2_.name as name2_2_2_ 
    from t_user_role userroleen0_ 
    inner join t_user userentity1_ on userroleen0_.user_id=userentity1_.id 
    inner join t_role roleentity2_ on userroleen0_.role_id=roleentity2_.id