Spring Data JDBC: Implementing Domain Driven Design Aggregate
Spring data jdbc is relatively new Spring data project. Spring data is around since more than a decade and Spring Data JPA being its most popular implementation is based on JPA specifications. Spring Data JPA works as persistence layer and allows to perform number of conventional tasks like saving, updating, fetching object using repository pattern. Spring Data JDBC does the same but keeping domain at heart. Lets dig it out further.
Spring Data JDBC allows to use persistence layer as per Domain Driven Design(DDD) requirements. DDD basically puts more focus on business domain and suggests approaches and patterns which helps tech team to design complex business applications. DDD is extremely useful when designing microservices driven architecture. The concept of aggregate is an integral part of DDD. A DDD aggregate is a cluster of domain objects that can be treated as a single unit. Spring Data JDBC facilitates developers to implement aggregate at persistence layer. This is the core theme of this post and I will be explaining this through an example.
Hold on if you are confused about DDD and aggregate? Martin Fowler has written an excellent article on the subject. Have a look here
Lets start with Spring Data JDBC dependency. Since I am using maven here, let me share maven dependency below;
Coming to entities, I here have two entities namely Client and Project. In this example, client can have multiple projects associated as obvious from the entities. Sharing sample entities below;
I am keeping entities simple for brevity. No need to use @Entity annotation when using Spring Data JDBC. Our client entity here will act as root aggregate meaning we wont need to persist project separately. There are also no bidirectional mapping option available because one entity works as root to another. Only root entity will carry the mapping in Spring Data JDBC.
Jumping to repositories, here is my root aggregate i.e ClientRepository;
Since I am done with entities and repository, about time to utilize these to persist data. Here’s how we can add client with projects. Client working as root aggregate here- with client, all projects will be persisted as well. A working service level method is shown below;
This method persists both client and its projects. Client works as root aggregate here and projects don't need to persisted separately.
Spring Data JDBC does not generate or update schemas for us unlike Spring Data JPA. We have got to do it ourselves using .sql file or flywaydb migration scripts. I would recommend using flywaydb versioning and migration scripts. But here I am using the simplest approach for the sake of brevity using schema.sql file shown below;
This post was never intended to show you to develop microservice using DDD but rather how we can start using DDD concepts in Spring world using Spring Data JDBC and to show you how much it facilitates in this aspect.
Complete working code along with tests for this example can be found here on GitHub. Hope you enjoyed the post. Will be happy to see your comments, questions or any issue you find in the approach.