Stop Rewriting the Same Spring Data JPA Code in Every Project

java dev.to

I Got Tired of Rewriting the Same Spring Data JPA Code

After building enough Spring Boot applications, I noticed something strange.

No matter what the application was—a REST API, an internal tool, or a microservice—the persistence layer always started the same way.

I would create a BaseEntity.

Then an AuditableEntity.

Then a repository base class.

Then pagination models.

Then DTOs.

Then a generic Specification builder.

Then projection utilities.

Every.

Single.

Project.

The business logic changed.

The persistence infrastructure didn't.

Eventually I asked myself:

Why am I rebuilding the same foundation every time I start a new application?

That question became nerv-persistence.

Not another ORM.

Not a replacement for Spring Data JPA.

Just a reusable persistence foundation for applications that have already outgrown copy-pasting infrastructure between repositories.


The moment I realized something was wrong

It happened while creating a new service.

I copied my old BaseEntity.

Then my audit fields.

Then my repository interfaces.

Then my Specification utilities.

Again.

Nothing I was writing was specific to the application.

I was spending the first few hours rebuilding plumbing instead of solving business problems.

I'm guessing many Spring developers have done exactly the same thing.


The hidden cost of "just copy it"

Copying code feels free.

Until six months later.

One project fixes a bug.

Another project improves the Specification builder.

A third project adds projection support.

Now every application has a slightly different version of the same infrastructure.

Maintaining consistency becomes harder than writing the code in the first place.

I wanted a single place where those common building blocks could evolve together.


What ended up inside the library?

Instead of trying to become another framework, I focused on extracting the pieces I kept rebuilding.

The library includes reusable entity foundations like:

  • BaseEntity
  • BusinessEntity
  • AuditableEntity
  • EnableEntity

It also provides common API models for things like slice pagination and reference data.

On the repository side, I extracted reusable repository implementations, projection support, and slice-based repositories that I found myself implementing over and over.

But the part I'm probably happiest with is the dynamic query support.

If you've worked with Spring Data JPA Specifications, you know how powerful they are...

...and how quickly the surrounding infrastructure grows.

Search criteria.

Builders.

Operators.

Generic specifications.

Projection utilities.

Most applications eventually reinvent this wheel.

So I stopped copying it between projects and turned it into reusable components instead.


One philosophy guided the entire project

Whenever I had to make a design decision, I asked myself one question:

Would I want to maintain this in ten different repositories?

If the answer was "no," it belonged in the library.

That kept the project surprisingly focused.

Rather than replacing Spring Data JPA, it simply removes the repetitive code that tends to accumulate around it.


What's next?

This is only the initial release.

There are still plenty of ideas I'd like to explore as the project grows.

More importantly, I want the library to evolve from real-world usage rather than assumptions.

If there's a persistence problem you've solved repeatedly, I'd genuinely like to hear about it.

Those are usually the best candidates for reusable abstractions.


The project is available on Maven Central, and the source code is on GitHub:

🔗 https://github.com/czetsuyatech/nerv-persistence

If you have feedback, ideas, or feature requests, I'd love to hear them.

After all, this library exists because I got tired of solving the same problem over and over again. I'm sure I'm not the only one.

Source: dev.to

arrow_back Back to Tutorials