spring-boot - 尽管获取加入,但无法解决 @ManyToOne n+1 呼叫
问题描述
我遇到了一个问题,我无法解决特定的延迟提取,导致 n+1 调用。尽管对我需要的资源使用了 join fetch。
这是我的实体:
@Entity
@Table(schema = "dbo", name = "Authorization")
public class Authorization {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Id")
private Integer id;
.............
@Column(name = "Auditor")
private String auditor;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "auditor", referencedColumnName = "UserId", insertable = false, updatable = false)
private User auditorUser;
@Column(name = "Analyst")
private Integer analyst;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "Analyst", referencedColumnName = "Id", insertable = false, updatable = false)
private User analystUser;
@OneToMany(mappedBy = "authorization", cascade = CascadeType.ALL)
private Set<Approver> approvers;
.............
}
@Entity
@Table(name = "[User]")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Id")
private int id;
@NaturalId
@Column(name = "UserId")
private String userId;
}
@Entity
@Table(name = "Approver")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Id")
private int id;
@Column(name = "ApproverId")
private String approverId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ApproverId", referencedColumnName = "UserId", insertable = false, updatable = false)
private User approverUser;
}
我正在尝试获取所有授权并加入获取它的关联审计用户、分析用户和批准者。这是我对 queryDSL 所做的事情:
QUser auditorUser = new QUser("auditorUser");
QUser analystUser = new QUser("analystUser");
QUser approverUser = new QUser("approverUser");
List<Authorization> auths = repo.findAll(
new JPAQuery<Authorization>()
.from(authorization)
.leftJoin(authorization.auditorUser, auditorUser).fetchJoin()
.leftJoin(authorization.analystUser, analystUser).fetchJoin()
.leftJoin(authorization.approvers, approver).fetchJoin()
.leftJoin(workAuthorizationApproverEntity.approverUser, approverUser).fetchJoin()
);
这会产生:
select authorization
from Authorization authorization
left join fetch authorization.auditorUser as auditorUser
left join fetch authorization.analystUser as analystUser
left join fetch workAuthorizationEntity.approvers as workAuthorizationApproverEntity
left join fetch authorization.approvers as approver
left join fetch approver.approverUser as approverUser
but it also then generates for every authorization one of these:
select user0_.Id as Id1_338_0_, user0_.UserId as UserId5_338_0_ from [User] user0_ where user0_.UserId=?
从用户 id 中,我可以识别出这是来自正在加入 User 表中 NaturalId 的 auditUser 。然而,在同一个班级中,分析师加入主键 id 并且工作正常。
发生了什么事,我能做些什么来防止这种情况发生?
解决方案
推荐阅读
- ios - 在以“podcast://”为前缀的 URL 上调用 open(_:options:completionHandler:) 会导致 iOS 播客应用在原始 URL 前添加“http://”
- javascript - Can't display state values in React child component
- android - java.io.IOException: Cannot run program CreateProcess error=2, 系统找不到android studio上指定的文件
- laravel - Laravel 如何让 url 成为 .env 中的内容
- javascript - 如何处理多个新行,直到在javascript中到达一个空行?
- java - 当 if 条件为常量时,为什么未检测到无法访问的代码?
- javascript - 无法上传文件
- java - 井字游戏 - 2 个带碎片的棋盘
- php - Doctrine\DBAL\Driver\PDOException SQLSTATE[HY000] [2006] MySQL 服务器已消失
- c++ - 是否可以将模板参数转发给 make_* 而无需扣除?