DEV Community

Salad Lam
Salad Lam

Posted on

1

Spring Data JPA: About Specification interface

org.springframework.data.jpa.domain.Specification interface

The objective of Specification interface is to let developers make reusable Predicates objects to append into a query when needed.

For example, to create a query of this entity.

@Entity
@Table(name = "Customer")
public class Customer {

    @Id
    @Column(name = "custId")
    private Integer custId;
    @Column(name = "companyName", length = 40, nullable = false)
    private String companyName;
    @Column(name = "contactName", length = 30)
    private String contactName;
    @Column(name = "contactTitle", length = 30)
    private String contactTitle;
    @Column(name = "address", length = 60)
    private String address;
    @Column(name = "city", length = 15)
    private String city;
    @Column(name = "region", length = 15)
    private String region;
    @Column(name = "postalCode", length = 10)
    private String postalCode;
    @Column(name = "country", length = 15)
    private String country;
    @Column(name = "phone", length = 24)
    private String phone;
    @Column(name = "mobile", length = 24)
    private String mobile;
    @Column(name = "email", length = 225)
    private String email;
    @Column(name = "fax", length = 24)
    private String fax;

    // ignore getter and setter
}
Enter fullscreen mode Exit fullscreen mode

In order to pass Specification criteria, please add org.springframework.data.jpa.repository.JpaSpecificationExecutor into the Repository interface.

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer>, JpaSpecificationExecutor<Customer> {
}
Enter fullscreen mode Exit fullscreen mode

null Specification

null Specification means no criteria.

customerRepository.findAll((root, query, criteriaBuilder) -> null);
// it is equal to customerRepository.findAll();
Enter fullscreen mode Exit fullscreen mode

To get entities when a field is equal to something

To get entities whose "city" is equal to the value of the String variable "city".

String city;
// ...
Specification<Customer> s = (root, query, criteriaBuilder) -> null;
if (Objects.nonNull(city)) {
    s = s.and((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("city"), city));
}
customerRepository.findAll(s);
Enter fullscreen mode Exit fullscreen mode

and() This is used for joining two Specification with AND clauses. The other one is or().

Add one more Specification

In addition to "city", "companyName" wants to look up also.

String city;
String companyName;
// ...
Specification<Customer> s = (root, query, criteriaBuilder) -> null;
if (Objects.nonNull(city)) {
    s = s.and((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("city"), city));
}
if (Objects.nonNull(companyName)) {
    s = s.and((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("companyName"), companyName));
}
customerRepository.findAll(s);
Enter fullscreen mode Exit fullscreen mode

Code about can work on cases from no query criteria to with "city" and "companyName" criteria.

Other unnormal usage of Specification interface

You may do following

  • to JOIN other entity
  • to define complex sort if JpaSpecificationExecutor.findAll(Specification , Sort) cannot suit your need

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

Top comments (0)

AWS Q Developer image

Your AI Code Assistant

Ask anything about your entire project, code and get answers and even architecture diagrams. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Start free in your IDE

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay