Building a user management microservice (Part 3): Implementing and testing repositories
In the previous part there was fair amount coding involved over the course of implementing the domain model, which comprises all the logic a user registration process needs. In this third post, I went ahead and added a concrete JPA-based implementation of UserRepository, a JPA support module and some test cases.
Using XML for mapping Plain Old Java Objects
By just looking at UserRepository, probably you would think of any difficulties for adding a JPA-based implementation to it.
However, I mentioned in the first part, that we’d be using DDD (Domain-Driven Design) and as a consequence, no framework specific dependency (including JPA annotations) cloud be used in the model. The only viable option which remains is doing the mapping in XML. I think I haven’t touch an orm.xml file since 2010, if I correctly recall, so I started to craft it with nostalgia.
Don’t want to miss a thing?
If you like technology as much as I do, you might consider signing up for a few of my newsletters.There are some problems with the configuration of the opt-in shortcode
DDD is a persistence ignorant approach, hence persisting a model which wasn’t designed with the target data store in mind might be challenging. Of course, it also has got that advantage that a real-world problem gets modeled directly and not just as a side effect of using a certain technology stack in a certain way.
The natural way how authorities (~privileges) of a User can be modeled is a simple set of strings or enumerated values.
Using a document database like MongoDB would make this model so easy and natural to persist. It might look like this. (BTW, I plan to add a Mongo-based repository implementation later in this series as well)
With relational modelling however, the concept of Authority has to be handled as a child relation to User. Yet, in the real world this is just a set of authorities. How do we bridge that gap?
ElementCollection which was introduces in JPA 2.0 comes to the rescue. It’s similar to OneToMany in its semantics. In this case the configured JPA provider (Hibernate) generated the necessary child relation automatically.
New modules in the project
springuni-auth-user-jpa is the one I’ve been talking about so far, which contains a concrete JPA-based implementation of UserRepository. The objective was that every module should have merely those dependencies which absolutely necessary to their operation. This one only needs to depend on the JPA API.
springuni-commons-jpa is a support module for being able to use a pre-configured combination of HikariCP and Hibernate as the entity manager without having to care about the details. It’s featuring AbstractJpaConfiguration , which is similar to Spring Boot’s HibernateJpaAutoConfiguration.
The reason why I didn’t use the latter was that Spring Boot’s auto-configuration takes some to initialize. As one of my target platform’s is Google App Engine Standard Environment, fast start-up time is critical.
Unit testing repositories
Altought someone might argue that there’s not much to test on a repository, especially if you’re using Spring Data’s Repository interfaces , yet I think that a couple of runtime issues can be avoided by doing that. For example wrong entity mapping or wrong JPQL queries.
This test case starts up a Hibernate-powered entity manager with an embedded H2 database. H2 is very good for testing, because it supports compatibility modes with bunch of well-known databases, such as MySQL. This way it can mimic your real DB.