【发布时间】:2021-12-27 03:11:13
【问题描述】:
我正在尝试使用 JPQL 生成单个 SQL 语句来获取多个不同的实体,这些实体都通过外键相互链接。
型号
模型如下所示:
@Entity
@Table(name = "mainentity")
@Data
@IdClass(MainEntityPrimaryKey.class)
public class MainEntity {
@Id
@Column(updatable = false)
private String foo;
@Id
@Column(updatable = false)
private String bar;
@OneToMany(cascade = {CascadeType.ALL}, orphanRemoval = true)
@JoinColumns({
@JoinColumn(name = "foo", referencedColumnName = "foo"),
@JoinColumn(name = "bar", referencedColumnName = "bar")
})
private List<SubEntity> subs;
}
@Entity
@Table(name = "subentity")
@Data
@IdClass(SubEntityPrimaryKey.class)
public class SubEntity {
@Id
@Column(updatable = false)
private String foo;
@Id
@Column(updatable = false)
private String bar;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "first_possibility_id", referencedColumnName = "first_possibility")
private FirstPossibility firstPossibility;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "second_possibility_id", referencedColumnName = "second_possibility")
private SecondPossibility secondPossibility;
}
@Entity
@Table(name = "firstpossibility")
@Data
public class FirstPossibility {
@Id
@Column(name = "first_possibility_id", nullable = false, updatable = false)
private String id;
@Column
private String something;
}
@Entity
@Table(name = "secondpossibility")
@Data
public class SecondPossibility {
@Id
@Column(name = "second_possibility_id", nullable = false, updatable = false)
private String id;
@Column
private String stuff;
}
SubEntity 永远不会同时链接 FirstPossibility 和 SecondPossibility。
存储库
Spring-Data 接口:
public interface MainEntityCRUDRepository extends CrudRepository<MainEntity, MainEntityPrimaryKey> {
@Query("SELECT main FROM MainEntity main WHERE CONCAT(main.foo, '~', main.bar) IN :ids")
List<MainEntity> getAllMainWithConcatenatedIds(@Param("ids") Collection<String> ids);
}
当前状态
事实上,它在对数据库的一次调用中正确地获取了所有MainEntity(我可以看到spring.jpa.show-sql=true属性正确地发生了绑定),但没有任何SubEntity。
SubEntity 会在代码稍后尝试访问它们时被获取,并且最终也会获取 First 或 Second 实体。所有这一切,对每个实体都有单独的 DB 调用(这在性能方面是我们想要避免的)。
重要提示:我们使用EclipseLink 作为我们的 JPA 提供者。
【问题讨论】:
-
请参阅 stackoverflow.com/a/37596251/496099 和 stackoverflow.com/a/16693590/496099 以了解 JPA/EclipseLink 中的嵌套 fetch 连接,但在通过 OneToMany 和 ManyToMany 连接时要小心父行中的内容,因为某些数据可能会导致开销超过加入的好处。例如,如果它有大量的 lobs/clob 数据,您可能希望查看批量获取,以减少网络在交叉连接这些关系时必须处理重复行。
标签: java jpa spring-data-jpa spring-data eclipselink