java 如何在JPA Enity中获得一对多字段的计数?

r6hnlfcb  于 2023-02-28  发布在  Java
关注(0)|答案(2)|浏览(125)

我们如何才能获得JPA实体的OneToMany字段的计数作为每个父实体的查询计数,而作为列表获取成本很高,而且在JPA Repository中没有办法。
我想得到每个PostEntity的喜欢和评论的数量。该字段是懒惰获取类型,如果我调用likes.size()comments.size(),那么它将加载所有的评论和喜欢从数据库,可以有成千上万的评论和喜欢。
我知道我可以为喜欢和评论创建一个单独的repo来获得计数,但是当从PostRepository调用方法时,如何获得每个实体的计数?什么是最好和有效的方法?

父实体

@Entity
@Table(name = "posts")
@Getter
@Setter
public class PostEntity extends MappedSuperClassEntity<UserEntity> {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Nullable
    private String title;

    @Nullable
    private String postText;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="user_id")
    private UserEntity user;

    @Nullable
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "community_id")
    private CommunityEntity community;

    @OneToMany(fetch = FetchType.LAZY)
    private List<CommentEntity> comments;

    @OneToMany(fetch = FetchType.LAZY)
    private List<LikeEntity> likes;

    @Transient
    private int numberOfLikes;

    @Transient
    private int numberOfComments;
}

我想在查询帖子列表时获得每个帖子实体的喜欢和评论计数。我的Repo

public interface PostsRepository extends PagingAndSortingRepository<PostEntity, Integer> {
    @Query(value = "SELECT P FROM PostEntity P WHERE P.user.id = :userId ORDER BY P.createdDate DESC")
    Page<PostEntity> getUserPosts(int userId, Pageable pageable);

    @Query(value = "select P from PostEntity P where p.community.id = :communityId order by P.createdDate desc")
    Page<PostEntity> getCommunityPosts(int communityId, Pageable pageable);
}

我搜索了很多,有人建议使用@Formula注解对实体字段进行自定义查询,但@Formula是特定于Hibernate的,不知道它是否适用于@Transient字段。是否有任何JPA特定的方法可以做到这一点,因为这是一个常见的问题。

xzlaal3s

xzlaal3s1#

您需要带有EXTRA选项的“LazyCollection”注解。

@OneToMany(fetch = FetchType.LAZY)
@LazyCollection(LazyCollectionOption.EXTRA)
private List<CommentEntity> comments;

该注解允许在不加载的情况下访问“size()”。
你可以看看这篇文章。
https://www.baeldung.com/hibernate-lazycollection
有时候,我们只关心集合的属性,并不需要集合中的对象。例如,回到分支和Employees的例子,我们可能只需要分支中的雇员数量,而不关心实际雇员的实体。在这种情况下,我们考虑使用EXTRA选项。让我们更新我们的示例来处理这种情况。与前面的情况类似,分支实体与Employee实体具有id、name和@OneToMany关系。但是,我们将@LazyCollection的选项设置为EXTRA:
我试图添加评论,但我没有写评论访问,因为声誉,所以我发送一个答案。

oogrdqng

oogrdqng2#

这对我很有效( Boot ),但是当在关联的存储库中使用本机查询时,我遇到了一些问题。

@Formula(value = "(SELECT count(*) FROM task_comments " +
    "WHERE task_comments.task_id=task_id)")
private Long totalComments;

相关问题