How to create a custom Repository class in Spring JPA?

A custom repository in Spring Data JPA is created by defining a repository interface that extends JpaRepository (or CrudRepository) with your entity and ID types, optionally adding your own derived or @Query-annotated methods beyond the built-in CRUD operations.

Key Points: • Extending JpaRepository<Entity, IdType> immediately gives you all standard CRUD, paging, and sorting methods without writing an implementation. • Additional methods can be added directly to the interface using Spring Data's method-name query derivation or the @Query annotation. • For genuinely custom logic that can't be expressed declaratively, you define a separate "Custom" interface plus an "Impl" implementation class, and have the main repository interface extend the custom interface too. • Spring automatically detects and wires the custom implementation as long as the naming convention (RepositoryNameImpl) is followed.

Example: A ProductRepository needs both the standard CRUD methods and a custom method to find discounted products, so it extends JpaRepository and adds a derived method, findByDiscountGreaterThan(BigDecimal amount), without needing to write any SQL by hand.

Code Example:

public interface ProductRepository extends JpaRepository<Product, Long> {
    List<Product> findByDiscountGreaterThan(BigDecimal amount);

    @Query("SELECT p FROM Product p WHERE p.category = :category")
    List<Product> findByCategory(@Param("category") String category);
}

Interview Tip: A concise interview answer is:

"I extend JpaRepository with the entity and ID type to get all the standard CRUD, paging, and sorting behavior for free, then add my own methods either through Spring Data's derived-query naming or with @Query for anything more custom. For logic too complex to express declaratively, I'd add a separate custom interface and Impl class that Spring Data automatically wires in."