Specification Pattern for Complex Query Building
Fast recall
Quick revision
Core answer
Ability to design composable query logic and knowledge of Spring Data JPA's dynamic query support
Concatenating JPQL strings or adding @Query methods for every filter combination — this creates an exponential number of methods
Show how to combine specifications with AND/OR, mention Querydsl as an alternative, and explain when Criteria API is overkill vs necessary
Interview-ready guide
Interview answer
The Specification pattern solves the combinatorial filter problem. If a search page has 5 optional filters, you'd need up to 32 @Query methods to cover every combination. That's unworkable. Specification encapsulates each filter as a composable object.
In Spring Data JPA, each Specification is a functional interface with three parameters — Root, CriteriaQuery, and CriteriaBuilder — that returns a JPA Predicate. The key design decision is returning cb.conjunction() (an always-true predicate) when the filter value is null, so specifications compose safely regardless of which filters are active.
You compose them fluently: Specification.where(hasCategory(cat)).and(priceBetween(min, max)).and(nameLike(keyword)). Each combinator creates a new specification by wrapping the predicates. The repository's findAll(spec, pageable) translates the composed specification into a single SQL query with the appropriate WHERE clause.
The result is dynamic queries that are readable, independently testable — each specification can be verified with a @DataJpaTest using seeded data — and extensible without changing existing code. Adding a new filter means adding one static method.
The main tradeoff is verbosity. For fixed, static queries, a @Query annotation is simpler and more direct. Use Specifications for user-driven search pages and admin dashboards where filter combinations are dynamic. Querydsl is a type-safe alternative that replaces string-based field names with generated Q-classes — compile-time checking at the cost of build complexity.
Specification Pattern for Complex Query Building
Direct Answer
The Specification pattern encapsulates a single query criterion as an object. Complex queries are built by combining specifications with AND, OR, and NOT combinators. Spring Data JPA's JpaSpecificationExecutor uses this directly — each Specification<T> becomes a JPA Predicate, allowing dynamic queries without query string concatenation.
Common Mistakes & Pitfalls
Concatenating JPQL strings or adding @Query methods for every filter combination — this creates an exponential number of methods
Check your understanding
Answer these without looking back at the article.
- How does the Specification pattern differ from Querydsl?
- How would you unit test a single Specification without a database?
- Can you combine Specifications that span multiple joins?
Related interview prep categories
2Want a guided curriculum order?
These modules are also sequenced in our flagship backend interview track — open it when you prefer an ordered path instead of browsing by topic.