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?