How to Use Spring Data JPA: Simple Guide with Examples
To use
Spring Data JPA, define an entity class annotated with @Entity, create a repository interface extending JpaRepository, and inject this repository to perform database operations. Spring Data JPA automatically provides implementations for common CRUD methods, so you write less code and focus on your business logic.Syntax
Entity class: Annotate a class with @Entity to map it to a database table. Use @Id to mark the primary key.
Repository interface: Create an interface extending JpaRepository<Entity, ID> to get CRUD methods automatically.
Service or component: Inject the repository and call its methods like save(), findById(), findAll(), and deleteById().
java
import jakarta.persistence.Entity; import jakarta.persistence.Id; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service; import java.util.Optional; @Entity public class User { @Id private Long id; private String name; // getters and setters } @Repository public interface UserRepository extends JpaRepository<User, Long> { } // Usage in a service or component @Service public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public User saveUser(User user) { return userRepository.save(user); } public Optional<User> getUser(Long id) { return userRepository.findById(id); } }
Example
This example shows a simple Spring Boot application using Spring Data JPA to save and retrieve a User entity from an H2 in-memory database.
java
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import jakarta.persistence.Entity; import jakarta.persistence.Id; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import java.util.Optional; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Bean CommandLineRunner run(UserRepository userRepository) { return args -> { User user = new User(1L, "Alice"); userRepository.save(user); Optional<User> foundUser = userRepository.findById(1L); foundUser.ifPresent(u -> System.out.println("User found: " + u.getName())); }; } } @Entity class User { @Id private Long id; private String name; public User() {} public User(Long id, String name) { this.id = id; this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } @Repository interface UserRepository extends JpaRepository<User, Long> { }
Output
User found: Alice
Common Pitfalls
- Forgetting to annotate the entity class with
@Entitycauses Spring Data JPA to not recognize it. - Not defining a primary key with
@Idleads to errors on startup. - Using the wrong generic types in the repository interface causes compilation errors.
- Not configuring a datasource or JPA properties properly results in connection failures.
- Trying to instantiate repository interfaces manually instead of letting Spring inject them.
java
/* Wrong: Missing @Entity annotation */ public class Product { @Id private Long id; private String name; } /* Right: Add @Entity annotation */ import jakarta.persistence.Entity; import jakarta.persistence.Id; @Entity public class Product { @Id private Long id; private String name; }
Quick Reference
Key Spring Data JPA interfaces and annotations:
| Term | Description |
|---|---|
| @Entity | Marks a class as a database entity mapped to a table |
| @Id | Marks the primary key field of an entity |
| JpaRepository | Interface providing CRUD and pagination methods for entity T with ID type ID |
| @Repository | Marks a repository interface for Spring to detect |
| save() | Saves or updates an entity |
| findById(ID id) | Finds an entity by its ID |
| findAll() | Returns all entities |
| deleteById(ID id) | Deletes an entity by its ID |
Key Takeaways
Annotate your data classes with @Entity and define a primary key with @Id.
Create repository interfaces extending JpaRepository to get CRUD methods automatically.
Inject repositories via Spring to perform database operations without manual implementation.
Configure your datasource and JPA properties correctly to avoid connection issues.
Avoid common mistakes like missing annotations or wrong generic types in repositories.