我有一个简单的2个JPA实体,它们之间有一个Join:
主要实体国家:
public class Country implements Serializable {
@Id
@Column(name = "MCC")
private String mcc;
......
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "mcc", referencedColumnName = "mcc")
private List<CountryInfo> countryInfo;
联合实体CountryInfo:
public class CountryInfo implements Serializable {
@Id
@Column(name = "id")
private Long id;
@Column(name = "mcc")
private String mcc;
@Column(name = "continent")
private String continent;
当我打开我的配置来转储正在执行的查询时,我注意到对于找到的每个Country,在CountryInfo实体上使用指定的mcc进行另一个调用。
这显然很慢,因为它不是用JOIN创建一个调用,而是执行N + 1个查询(其中N = Country的计数)。
我已经看过这个教程https://zeroturnaround.com/rebellabs/how-to-use-jpa-correctly-to-avoid-complaints-of-a-slow-application/并进行了相应的更改,但它仍然调用N + 1查询..
有办法克服这个吗?
编辑
为了获得数据,我有一个存储库:@RepositoryRestResource(exported = false)
public interface CountryRepository extends JpaRepository<E212MCC, Long>,
JpaSpecificationExecutor<E212MCC> {
}
然后打电话说明一些规格:
List<E212MCC> countries = this.countryRepository.findAll(specifications);
由于您正在使用Specifications
,您可以尝试使用执行fetch连接操作的规范(我假设您正在使用JPA元模型):
private Specification<Country> joinContryInfo() {
return (root, query, cb) -> {
root.fetch(Country_.countryInfo);
// here you can fetch more entities if you need...
return null;
};
}
然后,把它添加到你的规范对象中:
Specifications.where(joinCountryInfo())
如果您不使用元模型,那么只需将Country_.countryInfo
替换为"countryInfo"
字符串。
如果您使用CountryInfo
字段进行搜索,您可以省略joinContryInfo()
规范,并在一个规范中准备连接和搜索查询:
private Specification<Country> continentEqual(String param) {
return (root, query, cb) -> {
Join<Country,CountryInfo> join = (Join) root.fetch(Country_.countryInfo);
return cb.equal(join.get(CountryInfo_.continent), addWildCards(param));;
};
}