Spring Data JPA repositories
Get CRUD and derived queries for free, and know which JPA settings matter in production.
Open this lesson in the learning hubKey points
- Extend
JpaRepository<Entity, Id>and Spring generates the implementation at startup. No code to write. - Method names become queries:
findByStatusAndTotalGreaterThanis parsed into JPQL. - For anything complex, write it yourself with
@Query. A ten-word method name is a smell. - Put
@Transactionalon the service method so several repository calls commit as one unit. - Use
ddl-auto: validateand a real migration tool (Flyway or Liquibase) in production — neverupdate. - Paginate list endpoints with
Pageable. UnboundedfindAll()is how services fall over.
Example
import jakarta.persistence.*;
import org.springframework.data.jpa.repository.*;
import org.springframework.data.domain.*;
@Entity
@Table(name = "orders")
public class Order {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String customerEmail;
@Enumerated(EnumType.STRING) // store the name, never the ordinal
private Status status;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List<LineItem> items = new ArrayList<>();
// getters / setters omitted
}
public interface OrderRepository extends JpaRepository<Order, Long> {
// Derived query - name is the specification
List<Order> findByStatusOrderByCreatedAtDesc(Status status);
Page<Order> findByCustomerEmail(String email, Pageable pageable);
@Query("select o from Order o join fetch o.items where o.id = :id")
Optional<Order> findWithItems(@Param("id") Long id); // avoids N+1
}
Declare the interface, get the queries — but own the schema and the fetch strategy yourself.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Spring Boot course, and every lesson in it is listed on the Spring Boot contents page.