Queries from method names
The ready-made JpaRepository methods cover work by key. The blog needs more: posts by one author, search by title. Spring Data can build a query from a method name. You declare a method like findByAuthor in the interface, and at startup Spring parses the name and writes the SQL itself.
New repository methods
// src/main/java/com/example/blog/PostRepository.java
package com.example.blog;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PostRepository extends JpaRepository<Post, Long> {
List<Post> findByAuthorOrderByCreatedAtDesc(String author);
List<Post> findByTitleContainingIgnoreCase(String text);
}The name reads like a phrase: "find by author, order by creation date descending". The second method finds posts whose title contains the text, ignoring case.
What Spring makes of the name
Hibernate prints the resulting SQL:
Hibernate: select p1_0.id,p1_0.author,p1_0.body,p1_0.created_at,p1_0.title from posts p1_0 where p1_0.author=? order by p1_0.created_at desc
Hibernate: select p1_0.id,p1_0.author,p1_0.body,p1_0.created_at,p1_0.title from posts p1_0 where upper(p1_0.title) like upper(?) escape '\'The method argument replaces ?. For Containing Spring wraps the text in % itself.
Service and controller
// src/main/java/com/example/blog/PostService.java
public List<PostResponse> findAll(String author) {
List<Post> found = author == null
? posts.findAll()
: posts.findByAuthorOrderByCreatedAtDesc(author);
return found.stream().map(PostResponse::from).toList();
}
public List<PostResponse> search(String text) {
return posts.findByTitleContainingIgnoreCase(text).stream()
.map(PostResponse::from)
.toList();
}// src/main/java/com/example/blog/PostController.java
@GetMapping
public List<PostResponse> list(@RequestParam(required = false) String author) {
return postService.findAll(author);
}
@GetMapping("/search")
public List<PostResponse> search(@RequestParam String q) {
return postService.search(q);
}Add a couple of posts and check:
curl "http://localhost:8080/api/posts?author=anna"
curl "http://localhost:8080/api/posts/search?q=spring"[{"id":2,"title":"Spring Data JPA","body":"Repositories","author":"anna","createdAt":"2026-10-04T09:37:51.263464Z"},{"id":1,"title":"Hello, Spring","body":"First post","author":"anna","createdAt":"2026-10-04T09:37:51.134416Z"}]
[{"id":1,"title":"Hello, Spring","body":"First post","author":"anna","createdAt":"2026-10-04T09:37:51.134416Z"},{"id":2,"title":"Spring Data JPA","body":"Repositories","author":"anna","createdAt":"2026-10-04T09:37:51.263464Z"}]Anna's posts came newest first, and the search for spring found both titles even though they spell Spring with a capital letter.
A name dictionary
| Name part | Example | SQL |
|---|---|---|
findBy, countBy, existsBy, deleteBy | countByAuthor | select, count, exists, delete |
And, Or | findByAuthorAndTitle | and, or |
Containing, StartingWith | findByTitleStartingWith | like |
IgnoreCase | findByTitleIgnoreCase | upper(...) |
After, Before, Between | findByCreatedAtAfter | >, <, between |
GreaterThan, LessThan | findByIdGreaterThan | >, < |
In | findByAuthorIn(List<String>) | in (...) |
OrderBy...Asc, Desc | findByAuthorOrderByTitleAsc | order by |
First, Top10 | findTop10ByOrderByCreatedAtDesc | limit |
You can return a List, an Optional (when you expect at most one result), a long for countBy and a boolean for existsBy.
Common mistake
The name is checked at startup. A typo in a field name stops the application:
No property 'titel' found for type 'Post'Here the method was called findByTitel. Names in the method must match the entity's fields, not the table's columns: CreatedAt, not created_at. If a name grows longer than a line, it is better to write the query by hand — that is the next lesson.