Overriding default methods of Spring MongoRepository

Miguel Rivero
Clarity AI Tech
Published in
3 min readOct 21, 2019

At our company, Clarity.ai, we’re using MongoDB as the main datasource for our SpringBoot-based product.

spring logo

Thus, we’re using Spring Data to access our databases and JPA to annotate our entity classes, and that way we take advantage of the simplicity and productivity that it usually brings to any development team. Sometimes the performance isn’t the best, but it’s all about making trade-offs…

One day though, we found that we needed to add some custom behaviors when we saved and restored data objects in some of our collections. We knew that it would be great if we could keep using Spring Data but we would need to be able to override or extend in some way the DB access logic that is automatically implemented by Spring when you use MongoRepository interfaces.

We scoured the internet, but we couldn’t find any article or StackOverflow entry that responded to our exact needs. We realized how to do it (based on Spring official documentation) and decided to write this article to share with the community.

Book Entity and BooksRepository

Suppose we have the following classes: Book, that represents an entity that will persist in our DB (in the book collection), including common book properties like the isbn, the title, a list with all the names of its authors, and the year of publication:

And BooksRepository, that extends MongoRepository so Spring will implement all methods we need to access our Books, in an “auto-magical” way:

Spring implements the common methods save(), findBy()… etc for us, but let’s now suppose we’re facing the following issue:

What if we knew that some of the book authors were incorrectly stored in our Books and we wanted to clean that info before we save or read any Book to/from MongoDB ?

The proper way would be probably to make a script and clean our DB with it, but for the purpose of this article, let’s suppose we can only achieve that by including a workaround in our code.

Overriding MongoRepository

Spring suggests composing our BooksRepository using new interface fragments and then redefining the methods we want to customize with exactly the same signature, including generic parameters. If we do so, Spring will prioritize our implementation over theirs:

And here is the implementation of that interface fragment that includes our workaround:

Probably you noticed something strange here: We didn’t specialize our implementation with <Book, String>. We kept the generic types <T, ID> instead, so we need to make some explicit type casts, even when our code will only manage Books persistence.

That is the tricky and not very intuitive part of the solution: You need to keep the same signature of all the methods for Spring to use your implementation instead of its own.

The final step is to add the new interface fragment to our original BooksRepository:

And voila! Every time a Book is stored in or retrieved from MongoDB, our method filterIncorrectAuthors() will be called, modifying the list of authors of a Book, removing all incorrect entries.

The rest of methods defined by MongoRepositoy but not overriden by our BookCustomizedMongoRepository will keep using the default Spring implementation, so if we call findAll() for instance, no cleaning of incorrect authors will be done.

Also notice that we are delegating the actual DB access to MongoTemplate, in order to keep using Spring Data in as much of our implementation as possible.

--

--

Miguel Rivero
Clarity AI Tech

Trying to improve World’s sustainability, starting with finances