DDD Specification Support in Hades
Join the DZone community and get the full member experience.
Join For FreeIn 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 :public static Specification<Book> bookByAuthorName(final String value) {
and the client code
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);
}
};
}@Test
public void shouldFindBookByAuthorNameSpecification() throws Exception {
List<Book> allBooks = bookDao.readAll(BookSpecifications.bookByAuthorName("shekhar"));
assertThat(allBooks.size(), is(equalTo(1)));
} public static Specification<Book> bookByAuthorAndPriceBetween(final String authorName, final double priceStart, final double priceEnd) {
return where(bookByAuthorName(authorName)).and(withPriceBetween(priceStart, priceEnd));
}
Opinions expressed by DZone contributors are their own.
Comments