Translating specifications into query predicates

I am trying to find a nice and elegant way to query the contents of a database based on DDD specifications.

A domain-driven design uses a specification to check if an object, also known as a candidate, meets a requirement (for a specific domain). For example, the IsTaskDone specification is as follows:

class IsTaskDone extends Specification<Task> { boolean isSatisfiedBy(Task candidate) { return candidate.isDone(); } } 

The above specification can be used for many purposes, for example. it can be used to verify the completion of a task or to filter all completed tasks from the collection. However, I want to reuse this beautiful, domain-specific specification for querying the database.

Of course, the simplest solution would be to get all the entities of our desired type from the database and filter this list in memory by cycling and deleting mismatched objects. But it is clear that this would not be optimal for performance, especially when the number of faces in our db increases.

Sentence

So, my idea is to create a "ConversionManager" that translates my specification into specific criteria for the preservation technique, think about the JPA predicate class. Services are as follows:

 public interface JpaSpecificationConversionManager { <T> Predicate getPredicateFor(Specification<T> specification, Root<T> root, CriteriaQuery<?> cq, CriteriaBuilder cb); JpaSpecificationConversionManager registerConverter(JpaSpecificationConverter<?, ?> converter); } 

Using our manager, users can register their own conversion logic, isolating the specification associated with the domain from the specific persistence logic. To minimize our manager’s configuration, I want to use annotations on my converter classes, allowing the manager to automatically register these converters.

JPA repository implementations can then use my manager through dependency injection to suggest a specification method lookup. Providing specification search should significantly reduce the number of methods in our repository interface.

In theory, everything sounds decent, but I feel like I have something critical. What do you guys think about my proposal, does it fit the DDD method? Or is there already a structure that does something identical to what I just described?

+4
source share
3 answers

Hades is a repository structure like a wrapper for JPA. This is DDD friendly. It supports DDD Specifications out of the box. I also suggest that you read this article from InfoQ .

+1
source

I really read this article, but hades specs require you to include JPA logic in your spec. Specifications are domain specific and should be kept separate from any type of robustness logic.

What about JPA annotations ...? Do you think your domain objects should be stored separately from JPA annotations?

I think the solution provided by Hades (now called spring-data-jpa ") is a better solution than the one presented in the Evans book: Eric Evans shows an example where the Specification calls the Repository, which he calls “Specification!” I really wondered how client code would only execute specs and not use the repository directly. The solution provided by Hades / Spring -data-jpa is good for me, it’s fine to put JPA in domain logic, since JPA is intended to go n and domain level.

EDIT: I forgot to mention that Eric Evans implements “double dispatch”, this is not a silly cyclical dependency between the specification and the repository, but as mentioned above, it does not prevent any developer from circumventing the specification.

0
source

In the .NET world, which is covered by LINQ . I do not know the Java equivalent.

-2
source

Source: https://habr.com/ru/post/1333588/


All Articles