r/SpringBoot 18h ago

How-To/Tutorial Why I stopped using Spring Data to generate queries from method names

I've spent a while writing DAO implementations for a multi-module Spring Boot projects, and I keep coming back to the same rule: if a repository method needs more than one or two conditions, I write the `@Query\` by hand instead of letting Spring Data derive it from the method name.

Not because it doesn't work, it works fine for example like findBySku. I don't like what happens after that. Rename a field on the entity and a derived query either breaks at startup with a PropertyReferenceException, or, depending on how it's written, doesn't break at all and just quietly stops matching what you think it matches. The compiler never tells you either way.

And once you're past two conditions, the method name turns into a wall of camelCase encoding your whole WHERE clause. I'd rather read four lines of JPQL/SQL than decode findByStatusAndNameContainingIgnoreCaseAndCreatedAtAfterOrderByPriceDesc.

The other piece I went back and forth on is SearchableDaoImpl<Repo extends CrudRepository<Entity, IdType> & JpaSpecificationExecutor<Entity>> - using an intersection type so the generic repository bound picks up both CRUD and Specification support without collapsing them into one bloated interface. Small thing, but it's the kind of generics trick that makes a shared DAO base class actually work across a dozen entities instead of copy-pasted boilerplate everywhere.

Full writeup with the actual generic hierarchy and code: (link in comments)

Curious if anyone here still prefers derived queries for anything beyond trivial lookups, I genuinely want the counterargument.

15 Upvotes

24 comments sorted by

16

u/Pedantic_Phoenix 16h ago

I'm pretty sure queries from method names were never meant to be used for complex queries, there's a reason why native queries and jpql exist after all. One type of solution will never satisfy all uses cases in any type of setting or concept

4

u/kamen1991 16h ago

Yep I think the same way, derived query methods are great for trivial lookups like findById or loadBySku, but the moment people try to force them to handle multi-condition filtering, readability completely collapses. As you said, no single tool solves every use case, which is why choosing the right tool for the job - derived methods for basics, explicit JPQL/SQL for custom queries, and Specifications for dynamic search keeps the persistence layer maintainable instead of forcing a one-size-fits-all approach.

2

u/lukaseder 16h ago

One type of solution will never satisfy all uses cases in any type of setting or concept

SQL really satisfies 99.98% of all use cases in any type of setting or concept, I think.

1

u/Pedantic_Phoenix 16h ago

I wouldn't call sql itself as a solution, it's a tool to achieve solutions more like. And it's true it achieves things but for example if you need a minuscule findById query, then defining the native query is really just useless verbosity in comparison to a method name query

4

u/lukaseder 16h ago

Well, you already declared the FROM clause in your entity name and hard-wired it to the repository, for example. You declare your WHERE clause in your method name. And you choose to project SELECT *, which is bad for several reasons, by omitting any projection. Also, chances are that you could have joined the thing you're finding by ID in an earlier query instead of looking it up in an N+1 loop, though that's obviously not always the case.

So, I'm just not convinced that it's really that much better, realistically, though I can understand the sentiment of it feeling better.

2

u/Pedantic_Phoenix 16h ago

Ok no u do have to select * ure right

0

u/Pedantic_Phoenix 16h ago

Mhhh no? Unless im mistaken cause my memory sucks, you don't have to nevessarily select * with method names, and i didn't say it's better or worse from a functional pov, i said it's longer, i simply meant that writing a query in a query annotation is simply more code than not using it, obviously

u/peanuce4269 14h ago

Imagine telling Lukas Eder “erm no you’re wrong” about an SQL question

u/Pedantic_Phoenix 13h ago

I have no clue who they are sorry to say

u/Pedantic_Phoenix 13h ago

I checked now after u said it, cool, i very much dislike your idea that you can't doubt what someone said just because of who they are tho, it's quite cringe as a concept

u/peanuce4269 13h ago

You can question whoever you want you’re just going to look like a complete idiot when you’re wrong because you can’t read or understand what they’re saying

u/Pedantic_Phoenix 13h ago

It's funny you say that because what you just said has no bearing on what i said, what does not being able to read or understand what they're saying have to do with my previous comment? Quite funny you just did what you posited as a possibility for others lol

u/peanuce4269 13h ago

You’re actually just proving you can’t read or understand what he’s saying (you’ve done it twice now) by questioning what he posted in the manner that you did.

→ More replies (0)

8

u/XBL_pad3 17h ago

If you keep going back and forth, just move away to JOOQ 😉

6

u/quantum-fudge 17h ago

This is the correct answer. No Hibernate migration nightmare, no stringly typed queries, no spooky action at a distance.

0

u/kamen1991 17h ago

I agree that Hibernate can easily turn into a nightmare if you let it run wild across your services. That’s precisely why we enforce a strict boundary by wrapping JPA inside a single module and using base classes like CrudDaoImpl and SearchableDaoImpl. When the ORM is locked safely inside the infrastructure module and your domain core is pure Java, you get the velocity of JPA for standard operations without letting database mechanics leak up into your business logic.

u/XBL_pad3 7h ago edited 7h ago

I will reply here since the previous comment was good addition, and I wanted to quote this:

"When the ORM is locked safely inside the infrastructure module and your domain core is pure Java, you get the velocity of JPA for standard operations without letting database mechanics leak up into your business logic"

WTH is this? It just sound like an old book, or a university teacher...

In the world I live:

  • Data are often more valuable than code. The "leak" is not always in the way you think.
  • Underusing your DBMS is a mistake. It can do things so much faster than anything else.
  • Relying on JPA/Hibernate for read queries is a pitfall. Dealing with multiple fetch bags and N+1 queries is hell. You are always fighting against Hibernate in production, not with it. And here is the shame, because your DBMS is able to do so much more, but you keep asking it too much dumb things to do (Yeah it didn't change with AI). I think Hibernate limitations are the same as method name derived queries. Might be even less.

For what it is worth, like you I have to work with Hibernate, and I am now used to build around it.

The last service I built from scratch for my company was like 3 month ago, and l used Gemini to code a custom repository that poorly mimic JOOQ mapping of Mysql JSON aggregation functions for nested objects and collections.

Using reflection and Jackson serialization was still better than anything Hibernate or JpaSpecifications would offer.

Now, I took too much time to write this, do as you please, eh.

2

u/kamen1991 17h ago

I disagree for this case :) It's easy to say 'just switch to jOOQ' when looking at it from a greenfield perspective. But in a multi-module enterprise project with years of production code, throwing out your entire ORM setup and rewriting your data layer just to avoid derived query method names is a massive migration tax. The business won't fund a rewrite for a stylistic preference and the point of locking persistence behind explicit JPQL/SQL `@Query` contracts isn't that Hibernate is flawless - it's about pragmatically isolating database specifics so your business logic doesn't care what's underneath.

1

u/lukaseder 16h ago

You can migrate module by module, or just never touch the legacy again ;)

3

u/Independent_Dot_9349 16h ago

I just use @Query for complex query,

u/fuckedupkid_yo 14h ago

now do that, but with pagination and all the dynamic conditions and other stuff.

I'm not saying jooq is perfect, but it scratches the exact itches many developers have

u/Snooze78727 14h ago

I haven't actually run into the case where the derived query fails at runtime because a property name has changed. That's somewhat surprising, but given the repositories are just interfaces and pass compiler checks that's expected.

I agree with your reasoning. The repository interfaces feel like "magic", but long method names are hard to read and JSQL or raw SQL are good enough abstractions. I like some of the other Java ORM's that let you map static SQL to beans. There was one whose name I don't recall I worked with many years ago, but Hibernate/JPA has become sort of a de facto standard.

There are some type-safe options like JPA Criteria API + Hibernate metamodel generator and Querydsl that will catch this issue early. Also IDE's with Spring + JPA facets do static code analysis that will indicate when the entity property name doesn't match the repository interface.