Repositories

What is a Repository?

In Spring Data JPA, a repository is an interface that provides a set of methods for performing CRUD (Create, Read, Update, Delete) operations on entities. Spring Data JPA provides implementation for these interfaces at runtime.

Creating a Basic Repository

To create a repository, you need to define an interface that extends one of Spring Data JPA’s repository interfaces. Here’s an example:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

In this example, UserRepository extends JpaRepository<User, Long>, where User is the entity type and Long is the type of the entity’s ID.

Repository Interfaces

Spring Data JPA provides several repository interfaces:

  1. CrudRepository: Provides CRUD functions

  2. PagingAndSortingRepository: Provides methods to do pagination and sorting records

  3. JpaRepository: Provides JPA related methods such as flushing the persistence context and deleting records in a batch

Custom Query Methods

Spring Data JPA allows you to define custom query methods by simply declaring their method signature. For example:

public interface UserRepository extends JpaRepository<User, Long> {
    User findByUsername(String username);
    List<User> findByEmailEndingWith(String domain);
}

Spring Data JPA will automatically implement these methods based on their names.

Using @Query Annotation

For more complex queries, you can use the @Query annotation:

public interface UserRepository extends JpaRepository<User, Long> {
    @Query("SELECT u FROM User u WHERE u.status = 1")
    List<User> findAllActiveUsers();

    @Query(value = "SELECT * FROM users WHERE email LIKE %?1", nativeQuery = true)
    List<User> findUsersByEmailDomain(String domain);
}

Best Practices

  1. Name your repository methods clearly and consistently.

  2. Use method name queries for simple queries and @Query for complex ones.

  3. Consider using projections for optimizing data fetching.

  4. Be cautious with modifying queries to ensure data integrity.

  5. Use @Transactional for methods that modify data.

In the next section, we’ll look at how to use these repositories to perform CRUD operations in your service layer.