QueryDSL fetchJoin 不获取数据
QueryDSL fetchJoin does not fetch the data
我遇到了这个问题:
假设我有 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
现在,目标是(为简单起见,有一些排序和过滤,但这不影响我的问题)return 所有 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 就像
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 returned
b.getC() 或 b.getA(),我正在向数据库发送另一个查询,我首先要避免的事情是什么。
我做错了什么?
我认为,连接条件的定义不合适。
希望我已经用 UserEntity <- UserRoleEntity -> 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
我遇到了这个问题:
假设我有 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
现在,目标是(为简单起见,有一些排序和过滤,但这不影响我的问题)return 所有 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 就像
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 returned
b.getC() 或 b.getA(),我正在向数据库发送另一个查询,我首先要避免的事情是什么。
我做错了什么?
我认为,连接条件的定义不合适。
希望我已经用 UserEntity <- UserRoleEntity -> 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