Over a million developers have joined DZone.

DDD Specification Support in Hades

DZone's Guide to

DDD Specification Support in Hades

· Java Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

In the first part of this series on Hades I talked about queries and finder support.  In this article, I will talk about another useful feature of Hades called Specification. Specification is a Domain Driven Design concept wherein you define a Predicate to check whether an object matches or does not match a criteria. Hades provides Specification support in the form Specification interface which is a wrapper over JPA Criteria API. The Specification interface provides a callback method that gets CriteriaBuilder, CriteriaQuery<T> and Root<T> as its arguments and returns a Predicate.

public interface Specification<T> {

Predicate toPredicate(Root<T> root, CriteriaQuery<T> query,
CriteriaBuilder builder);

Hades GenericDao interface provides two methods with Specification support.

List<T> readAll(final Specification<T> spec); // return list of entities matching spec
Page<T> readAll(final Specification<T> spec, final Pageable pageable); // returns a Page of entities matching the spec


Specification offers :

  1. You can easily plug-in new matching strategies: Specification is a strategy interface so it is easy to plug-in new criteria without changing the API. So, you can add strategies like bookByAuthorName or bookWithPriceLessThan or bookByAuthorWithPriceInBetween very easily.
    public static Specification<Book> bookByAuthorName(final String value) {
    return new Specification<Book>() {

    public Predicate toPredicate(Root<Book> root, CriteriaQuery<Book> query, CriteriaBuilder builder) {
    return builder.equal(root.get("author"), value);

    public static Specification<Book> withPriceBetween(final double start, final double end) {
    return new Specification<Book>() {

    public Predicate toPredicate(Root<Book> root, CriteriaQuery<Book> query, CriteriaBuilder builder) {
    return builder.between(root.<Double> get("price"), start, end);
    and the client code
    public void shouldFindBookByAuthorNameSpecification() throws Exception {
    List<Book> allBooks = bookDao.readAll(BookSpecifications.bookByAuthorName("shekhar"));
    assertThat(allBooks.size(), is(equalTo(1)));
  2. You can avoid intermingling different entities: suppose that we want to find all the books written by a particular author and Author is an entity of our application. So, if we don't use Specification, we will have to add a method findAllBooksByAuthor(Author author). So, our Book domain dao is now tightly coupled with Author and as we keep adding different entities it all gets dirty. So, with the help of Specification we can avoid this mess.
  3. You can reduce boiler plate code : with Specification you don't have to worry about writing the boiler plate code of creating the CriteriaBuilderCriteriaQuery<T> and Root<T>. You get all this via callback.
  4. You can combine Specifications : One of the coolest thing about Specifications is that you can build complex specifications by joining different specifications together. Hades provides a utility class called Specifications which provides utility methods to combine Specification instances. For example
     public static Specification<Book> bookByAuthorAndPriceBetween(final String authorName, final double priceStart, final double priceEnd) {
    return where(bookByAuthorName(authorName)).and(withPriceBetween(priceStart, priceEnd));

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}