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.