Data with JPACore· 40 min read

JpaRepository: Database Code for Free

Extend JpaRepository and Spring hands you save, find, delete and more — without writing any database code.

What you will learn

  • Create a repository interface
  • Use the built-in methods
  • Inject and use a repository

The magic interface

A repository is the object that talks to the database. The amazing part: you only write an interface (no code inside it), and Spring builds the working version for you at run time.

A repository — empty, yet fully working
import org.springframework.data.jpa.repository.JpaRepository;

public interface ProductRepository
        extends JpaRepository<Product, Long> {
    // empty! Spring provides the methods automatically
}

Note: Output: (No output — but Spring now provides a ready ProductRepository bean with save, findAll, findById, deleteById and more.) The two type parameters mean: this repository stores Product entities whose id type is Long.

What you get for free

MethodDoes
save(product)Insert or update a row
findAll()Get every row as a List
findById(id)Get one row by id
deleteById(id)Delete one row
count()Count the rows

Use it in a controller

Inject the repository (it is a bean) and call its methods:

Calling the free repository methods from a controller
@RestController
public class ProductController {
    private final ProductRepository repo;

    public ProductController(ProductRepository repo) {
        this.repo = repo;        // Spring injects the repository
    }

    @GetMapping("/products")
    public List<Product> all() {
        return repo.findAll();   // SELECT * FROM product
    }

    @PostMapping("/products")
    public Product add(@RequestBody Product p) {
        return repo.save(p);     // INSERT, then return the saved row (with id)
    }
}

Note: Output: POST /products {"name":"Mouse","price":499.0} -> {"id":1,"name":"Mouse","price":499.0} (id filled in by the database) GET /products -> [{"id":1,"name":"Mouse","price":499.0}] save inserted the row and returned it with its new id; findAll read it back. You wrote no SQL.

Tip: You can also add custom finders just by naming a method: List<Product> findByName(String name) in the interface, and Spring writes the query from the method name. Powerful and code-free.

Watch out: A repository works only for a class marked @Entity. Pointing a JpaRepository at a plain class will fail — JPA must know how to map it to a table first.

Q. Why does an empty interface that extends JpaRepository still work?

Answer: Spring Data JPA builds the implementation for you at run time, providing standard methods like save, findAll, findById and deleteById from the JpaRepository interface.

✍️ Practice

  1. Create a BookRepository interface extending JpaRepository<Book, Long> and use findAll() in a controller.
  2. Save two books with save() and list them with findAll().

🏠 Homework

  1. Create a StudentRepository and add a custom finder findByCourse(String course), then use it in an endpoint.
Want to learn this with a mentor?

CodingClave runs guided, project-based training (28-day, 45-day & 6-month batches).

Explore Training →