QueryDSL fetchJoin 不获取数据

问题描述

我正面临这个问题:

假设我有 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 记录

所以我正在做这样的事情(我习惯于使用 spring-data-jpa 来(左)JOIN FETCH 属性以避免按需延迟加载以防止将无用的查询发送到数据库中,我想做完全相同的事情在 QueryDSL 中)

    JPAQuery<DealBo> query = new JPAQuery<>(entityManager);

    query.select(qB)
            .from(qB)
            .innerJoin(qA).on(qA.a_id.eq(qB.id)).fetchJoin()
            .innerJoin(qC).on(qC.a_id.eq(qB.id)).fetchJoin()
            .fetch()

而且我希望有一个 sql,其中在 select 子句中有来自所有 3 个表(实体)的数据,其中 QueryDSL(或 Hibernate,我不完全确定什么工具将执行 sql -> 实体映射)将结果映射到实体对象. 但我真正得到的只是 select like

select b.id,b.someBfield from b
inner join a // join clause is right and omitted for simplicity
inner join b // join clause is right and omitted for simplicity

因此,当我调用一项时,QueryDSL 返回的内容例如

b.getC() 或 b.getA(),我正在向数据库发起另一个查询,首先我想避免什么。

我做错了什么?

解决方法

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

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

@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();

}

获取关联的表,随后对用户关联的迭代不会从数据库加载用户实体。

生成的 SQL 看起来像

    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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...