2021年5月2日星期日

How Can I Conditionally Combine Predicates For A JPA Query?

Lets say I have a Book Entity like this:

@Entity  @Table(uniqueConstraints = {          @UniqueConstraint(columnNames = {"title"})  })  class Book {      @Id      @GeneratedValue(strategy = GenerationType.AUTO)      Long id;      String title;      String author;      String description;  }  

and a repository like this:

@Repository  public interface BookRepository extends JpaRepository<Book, Long>, JpaSpecificationExecutor<Book> {        List<Book> findByAuthor(String author);      Book  findByTitle(String title);      List<Book> findByDescriptionContaining(String description);          static Specification<Book> hasTitle(String title) {          return (book, cq, cb) -> cb.equal(book.get("title"), title);      }         static Specification<Book> hasAuthor(String author) {          return (book, cq, cb) -> cb.equal(book.get("author"), author);      }         static Specification<Book> hasDescription(String description) {          return (book, cq, cb) -> cb.like(book.get("description"), "%" + description + "%");      }  }  

I can then do a query like this:

repository.findAll(where(hasAuthor("Robert Ludlum")).and(hasTitle("The Bourne Identity")).and(hasDescription("also a film"))).  

If I have this in a method with parameters, an empty or null value might be passed.
e.g. a REST API search endpoint that has optional parameters.

In that case I would only want to query by author repository.findAll(where(hasAuthor("Robert Ludlum"))) since adding the other predicates would return no results.

I want to start with a base query that includes everything, then if a parameter is not null add that predicate.
If the author was empty in the above example we wouldn't have a hasAuthor to start the Specification.

How can I conditionally combine the predicates in this way?

https://stackoverflow.com/questions/67362433/how-can-i-conditionally-combine-predicates-for-a-jpa-query May 03, 2021 at 09:04AM

没有评论:

发表评论