相关文章推荐
坚强的碗  ·  Cannot insert the ...·  2 月前    · 
刚毅的草稿纸  ·  使用 Async 和 Await ...·  1 年前    · 
微笑的充电器  ·  react usestate input ...·  1 年前    · 
安静的松鼠  ·  Pytorch ...·  1 年前    · 

在使用JPA做查询的时候,有时候要把实体对应的所有关联项都查询出来。下面的SellerListing实体中。"specificationConfigs","listingDocs"都是集合。使用@EntityGraph生成的sql语句全是LEFT OUTER JOIN。如果"specificationConfigs"有4条,"listingDocs"有3条,那查询出的数据就是3*4 = 12条。并且查询出的listingDocs、specificationConfigs会有重复的数据。

    @EntityGraph(attributePaths = {"product","productSpec","specificationConfigs","listingDocs"})
	@Query("SELECT DISTINCT listing FROM SellerListing listing WHERE listing.id=:id")
	SellerListing findWithDetailsById(@Param("id") Long id);

解决方法:参考 这里 。和 这里

要去除这些重复数据,使用数据库是不明智的。所有只有查询出来后在java程序中去除,我这里把属性声明为LinkedHashSet,并且重写ListingDoc实体的hashCode和equals方法。利用set集合不能放重复对象的属性。把重复数据去除掉。

@OneToMany(mappedBy="listing",fetch=FetchType.LAZY)
	private Set<ListingDoc> listingDocs = new LinkedHashSet<ListingDoc>();
public boolean equals(Object obj) {
		if (obj == null || !(obj instanceof BaseEntity))
			return false;
		BaseEntity target = (BaseEntity) obj;
		if(this.getId() == null || target.getId() == null)
			return false;
		return this.getId().equals(target.getId());
	public int hashCode() {
		return id == null ? 0 : id.hashCode();

特别注意:

如果查询出的是集合,并且要分页查询的时候。这种方式就有问题。因为分页是按照数据库数据分页的。查询出来再过滤,必然导致分页混乱。

    @EntityGraph(attributePaths = {"product","productSpec","specificationConfigs","listingDocs"})
	@Query("SELECT DISTINCT listing FROM SellerListing listing WHERE listing.title=:title")
	List<SellerListing> findWithDetailsByTitle(@Param("title") String title, Pageable pageable);