DZone
Java Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Java Zone > DDD Specification Support in Hades

DDD Specification Support in Hades

Shekhar Gulati user avatar by
Shekhar Gulati
·
Oct. 21, 10 · Java Zone · Interview
Like (0)
Save
Tweet
7.15K Views

Join the DZone community and get the full member experience.

Join For Free

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
    @Test
    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 CriteriaBuilder, CriteriaQuery<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));
    }


Domain-driven design Database Interface (computing) Book API Concept (generic programming) application Finder (software) Design

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • How to Determine if Microservices Architecture Is Right for Your Business
  • Making Your SSR Sites 42x Faster With Redis Cache
  • Cloud-Based Integrations vs. On-Premise Models
  • How to Test JavaScript Code in a Browser

Comments

Java Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo