📅 Join me: Clean Architecture for Backend Developers on Wed 26th Aug, 5:00 - 6:30 PM (CEST)
One of the biggest mistakes I see in Spring applications is developers mocking JPA.
When tests become slow, they replace the database with mocked JpaRepository interfaces.
The tests are faster.
But the architecture is now coupled to the ORM.
Why Mocking JPA Is a Design Smell
Developers mock JPA because they want:
fast tests
no database
isolated business logic
Those are good goals.
Mocking JPA isn’t.
Why?
You’re mocking a framework you don’t own
Your tests depend on Spring Data instead of your own abstractions
Changing persistence forces you to change unit tests
Business logic stays coupled to the ORM
The mock removes the database.
It doesn’t remove the dependency on the ORM.
The Real Problem
One team I worked with couldn’t upgrade their ORM for months because of a change to how inheritance was mapped.
The application wasn’t the problem.
The business logic wasn’t the problem.
The problem was that the ORM had leaked into the application layer and the tests.
A change in persistence rippled through the entire codebase.
A concrete example:
In .NET, EF Core's Table-Per-Hierarchy inheritance auto-adds a
Discriminatorcolumn, and its behavior has shifted across major versions — nullability, length, how it's configured and queried.An upgrade changes the discriminator, and that change ripples into every piece of code that touches those entities.
JPA has the same trap: single-table inheritance auto-creates a
DTYPEdiscriminator column, so a change to the mapping reaches straight into the application layer and its tests.

