【问题标题】:Getting collection object with JOIN FETCH using @Query with Pageable not working - Spring JPA使用带有Pageable的@Query获取JOIN FETCH的集合对象不起作用 - Spring JPA
【发布时间】:2021-09-14 13:00:33
【问题描述】:

尝试使用可分页的 JOIN FETCH 获取 Post 对象。但它抛出异常。

实体

@Entity
public class Post {
  @Id
  private String postId;
  private String postName;
  @OneToMany(mappedBy = "Post", cascade = CascadeType.ALL)
  private Set<PostTag> postTags = new HashSet<PostTag>();
}
@Entity
public class Tag {
  @Id
  private String tagId;
  private String tagName;
  @OneToMany(mappedBy = "tag", cascade = CascadeType.ALL)
  @JsonIgnore
  private Set<PostTag> postTags = new HashSet<PostTag>();
}
@Entity
public class PostTag {
  @EmbeddedId
  private PostTagId postTagId = new PostTagId();
  
  @ManyToOne(fetch = FetchType.LAZY)
  @MapsId("postId")
  @JoinColumn(name = "post_Id")
  @JsonIgnore
  private Post post;
  
  @ManyToOne(fetch = FetchType.LAZY)
  @MapsId("tagId")
  @JoinColumn(name = "tag_Id")
  private Tag tag;
  
  @OneToMany(mappedBy = "posttag", cascade = CascadeType.ALL)
  @JsonIgnore
  private Set<Items> items= new HashSet<Items>();

  private String someDateField;
}
@Embeddable
public class PostTagId implements Serializable {
  private String postId;
  private String tagId;
  //equals & hashcode ommited
}
public class Items{
  @Id
  private String itemId;
  private String itemName;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumns({@JoinColumn(name = "post_id"), @JoinColumn(name = "tag_id")})
  @JsonBackReference
  @JsonIgnore
  private PostTag postTag;

  @OneToMany(mappedBy = "items", cascade = CascadeType.ALL)
  @JsonIgnore
  private Set<SubItems> subItems= new HashSet<SubItems>();

}
public class SubItems{
  @Id
  private String subItemId;
  private String subItemName;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumns({@JoinColumn(name = "itemId")})
  @JsonBackReference
  @JsonIgnore
  private Items items;

}

仓库查询如下,

试过了,

@Query(value = "select po from Post po INNER JOIN FETCH po.posttags pts INNER JOIN FETCH pts.tag t INNER JOIN FETCH pts.items i INNER JOIN FETCH i.subitems LEFT OUTER JOIN po.posttags pts2 where (t.tagName like :tName) and (pts.someDateField between :startDate and :endDate) order by pts2.someDateField desc", countQuery = "select count(po) from Post po INNER JOIN po.posttags pts INNER JOIN pts.tag t INNER JOIN pts.items i INNER JOIN i.subitems LEFT OUTER JOIN po.posttags pts2 where (t.tagName like :tName) and (pts.someDateField between :startDate and :endDate) order by pts2.someDateField desc")
Page<Post> findAllInOneQuery(String tName, String startDate, String endDate, Pageable pageable);

但这会导致以下异常。

Caused by: org.hibernate.QueryException: illegal attempt to dereference collection [po0_.postId.postTags] with element property reference [someDateField]

但下面的 List 返回类型可以完美运行。为什么以及如何使用分页?

@Query(value = "select po from Post po INNER JOIN FETCH po.posttags pts INNER JOIN FETCH pts.tag t INNER JOIN FETCH pts.items i INNER JOIN FETCH i.subitems LEFT OUTER JOIN po.posttags pts2 where (t.tagName like :tName) and (pts.someDateField between :startDate and :endDate) order by pts2.someDateField desc", countQuery = "select count(po) from Post po INNER JOIN po.posttags pts INNER JOIN pts.tag t INNER JOIN pts.items i INNER JOIN i.subitems LEFT OUTER JOIN po.posttags pts2 where (t.tagName like :tName) and (pts.someDateField between :startDate and :endDate) order by pts2.someDateField desc")
    List<Post> findAllInOneQuery(String tName, String startDate, String endDate);

为什么 List 按预期工作,而不是 Page 对象。是否缺少任何参数或者我需要稍微更改查询以适应可分页?

【问题讨论】:

    标签: java spring hibernate jpa spring-data-jpa


    【解决方案1】:

    我阅读了您的问题,这是我的建议:

    要将 Pagable 与 @Query 注释一起使用,您必须为查询指定 countBy 属性。

    @Query(
    value = "select po from Post po INNER JOIN FETCH po.posttags pts INNER JOIN FETCH pts.tag t INNER JOIN FETCH pts.items i INNER JOIN FETCH i.subitems LEFT OUTER JOIN po.posttags pts2 where (t.tagName like :tName) and (pts.someDateField between :startDate and :endDate) order by pts2.someDateField desc", countQuery = "select count(po) from Post po INNER JOIN po.posttags pts INNER JOIN pts.tag t INNER JOIN pts.items i INNER JOIN i.subitems LEFT OUTER JOIN po.posttags pts2 where (t.tagName like :tName) and (pts.someDateField between :startDate and :endDate) order by pts2.someDateField desc",
    countBy = "select count(po) from Post po INNER JOIN FETCH po.posttags pts INNER JOIN FETCH pts.tag t INNER JOIN FETCH pts.items i INNER JOIN FETCH i.subitems LEFT OUTER JOIN po.posttags pts2 where (t.tagName like :tName) and (pts.someDateField between :startDate and :endDate) order by pts2.someDateField desc", countQuery = "select count(po) from Post po INNER JOIN po.posttags pts INNER JOIN pts.tag t INNER JOIN pts.items i INNER JOIN i.subitems LEFT OUTER JOIN po.posttags pts2 where (t.tagName like :tName) and (pts.someDateField between :startDate and :endDate)")
    Page<Post> findAllInOneQuery(String tName, String startDate, String endDate, Pageable pageable);
    

    【讨论】:

      猜你喜欢
      • 2020-12-10
      • 2021-09-11
      • 1970-01-01
      • 2021-12-19
      • 2018-03-20
      • 2017-08-21
      • 2014-02-28
      • 2011-08-14
      • 1970-01-01
      相关资源
      最近更新 更多