'Does Spring Data JPA have any way to find entity by count a field and don't use @Query?

For example: I want to find list book and count categories > 3. How to resolve it and don't use annotation Query in interface Repository?

package com.web.dacn.entity.book;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.web.dacn.entity.user.Author;
import com.web.dacn.entity.user.User;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Entity
@Table(name = "book")
@AllArgsConstructor
@NoArgsConstructor
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "name", 
            nullable = false, 
            columnDefinition = "NVARCHAR(100)")
    private String name;

    @Column(name = "thumbnail", columnDefinition = "TEXT")
    private String thumbnail;

    @Column(name = "view", 
            columnDefinition = "INTEGER DEFAULT 1",
            nullable = false)
    private Integer view;

    @Column(name = "price")
    private Double price;

    @Column(name = "vip")
    private Boolean vip;

    @Column(name = "description", 
            columnDefinition = "TEXT",
            nullable = false)
    private String description;

    @Column(name = "slug", 
            columnDefinition = "VARCHAR(2000)",
            nullable = false)
    private String slug;

    @Column(name = "meta_title",
            columnDefinition = "NVARCHAR(100)")
    private String metaTitle;
    
    @Column(name = "meta_description", columnDefinition = "TEXT")
    private String metaDescription;

    @Column(name = "status", 
            nullable = false, 
            columnDefinition = "INTEGER DEFAULT 1")
    private Integer status;

    @Column(name = "mod_time", nullable = false)
    private Date mod_time;

    @ManyToOne(cascade = CascadeType.ALL, targetEntity = User.class)
    @JoinColumn(name="mod_user_id")
    @JsonIgnore
    private User user;

    
    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "book_author", 
        joinColumns = @JoinColumn(name = "book_id", nullable = false), 
        inverseJoinColumns = @JoinColumn(name = "author_id", nullable = false))
    @JsonIgnore
    private List<Author> authors = new ArrayList<>();

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "book_bookcategory", 
        joinColumns = @JoinColumn(name = "book_id", nullable = false), 
        inverseJoinColumns = @JoinColumn(name = "category_id", nullable = false))
    @JsonIgnore
    private List<BookCategory> categories = new ArrayList<>();  
}


Solution 1:[1]

I am not sure there is another way to do it apart from using custom query. Instead, you can use stream api by doing this:

List<Book> books = repository.findAll();
List<Book> booksWithCategories = books.stream()
     .filter(book -> book.getCategories().size() > 3)
     .collect(Collectors.toList());

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Harry Coder