当映射的实体不存在时,如何防止在使用 QueryDSL 进行左外连接查询后延迟加载?

问题描述 投票:0回答:0

我有2张桌子

Team
Member
.

Team
Member
有 1:N 关系。

问题

在使用 QueryDSL 和 fetchJoin 进行第一个左外连接查询后访问不存在的“团队”字段时,如何防止延迟选择查询?

实体类定义

@Table(name = "member")
@Entity
class Member(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Int = 0,
    @Column(name = "team_id")
    var teamId: Long? = null,
    @Column(name = "name")
    var name: String? = null,
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "team_id", insertable = false, updatable = false, foreignKey = ForeignKey(name = "none"))
    val team: Team? = null,
)

@Table(name = "team")
@Entity
class Team(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long = 0,
    @Column(name = "name")
    var name: String? = null,
)

当前数据库状态

// team
+----+-------+
| id | name  |
+----+-------+
| 1  | team1 |
+----+-------+

// member
+----+---------+------+
| id | team_id | name |
+----+---------+------+
| 1  | 2       | John |
+----+---------+------+

QueryDSL 查询代码

val members = from(member)
    .leftJoin(member.team, team).fetchJoin()
    .fetch()

我只是希望在访问

team
类中的
Member
字段时不会发生延迟加载,并且只返回null,因为没有将FK作为PK的映射行。

但是,当我访问

team
字段时,将执行另一个选择查询以查找具有特定访问成员的 teamId 作为 PK 的团队表。 此外,由于没有给定 PK 的行,因此会出现以下错误。

Unable to find my.package.Team with id 2
javax.persistence.EntityNotFoundException: Unable to find my.package.Team with id 2
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$JpaEntityNotFoundDelegate.handleEntityNotFound(EntityManagerFactoryBuilderImpl.java:177)
    at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:298)
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:197)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:322)
    at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:45)
    at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95)
... (omitted)

但是,如果我将数据库中现有成员的 team_id 列从 2 更改为 1,这是现有团队的主键,则不会执行另一个选择查询,并且团队对象已经加载到成员对象中,仅在第一个连接查询中。

mysql jpa spring-data-jpa spring-data querydsl
© www.soinside.com 2019 - 2024. All rights reserved.