简体   繁体   中英

How to get Count of OneToMany field in JPA Enity?

How can we get the count of OneToMany field of JPA entity as querying count for each parent entity while fetching as a list is costly and there is no way in JPA Repository.

I want to get the number of likes and comments for each PostEntity . The field is Lazy fetch type and if I call likes.size() or comments.size() then it will load all of the comments and likes from database and there can be thousands of comments and likes.

I know I can create a seperate repo for likes and comments to get the counts but while calling method from PostRepository how to get the counts for each and every entity? What is the best and efficient way?

Parent Entity

@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;
}

I would like to get the likes and comments count for each PostEntity while querying for the list of posts. My 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);
}

I searched for a lot and someone suggested to use @Formula annotation for custom queries on the entity field but @Formula is hibernate specific and don't know if it works with @Transient field. Is there any JPA specific way to do that as it's a common problem.

You need "LazyCollection" annotation with EXTRA option.

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

This annotation would allow to access "size()" without loading.

You can check this article.

https://www.baeldung.com/hibernate-lazycollection

Sometimes, we're only concerned with the properties of the collection, and we don't need the objects inside it right away. For example, going back to the Branch and the Employees example, we could just need the number of employees in the branch while not caring about the actual employees' entities. In this case, we consider using the EXTRA option. Let's update our example to handle this case. Similar to the case before, the Branch entity has an id, name, and an @OneToMany relation with the Employee entity. However, we set the option for @LazyCollection to be EXTRA:

I try to add comment but i have no writing comment access because of reputation so i send an answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM