Unable to resolve @ManyToOne n+1 calls despite fetch join

I’m running into an issue where I’m unable to resolve a particular lazy fetch, leading to n+1 calls. This is despite using join fetch for the resources that I need.

Here’s are my entities:

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

    @Column(name = "AuthorizationId")
    private Integer authorizationId;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "AuthorizationId", referencedColumnName = "Id", insertable = false, updatable = false)
    private Authorization authorization;
}

I’m trying to grab all the Authorizations and join fetch it’s associated auditorUser, analystUser, and approvers. Here’s what I’m doing with 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()
);

this generates:

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=? 

From the user id, i can recognize that this is coming from the auditorUser that is joining to a NaturalId in User table. In the same class, however, the analyst joins to the primary key id and works fine.

What is going on and what can I do to prevent that from happening?

Edit: Upon further investigation, I found that the n+1 calls are only coming when I use the

left join fetch authorization.approvers as approver

part. Leaving that out doesn’t result in n+1.