@Repository Annotation in Spring

In this tutorial, you will learn what the @Respository annotation is and how to use it in your Spring Boot applications.

@Repository is a Spring annotation that indicates that the decorated class is a repository. A repository is a mechanism for encapsulating storage, retrieval, and search behaviour which emulates a collection of objects.

How to use @Repository Annotation

You will use @Repository annotation to indicate that the decorated class is a repository and that the class is a stereotype. This stereotype indicates that the class is responsible for storing, retrieving, and searching for objects.

To use the @Repository annotation in Spring Boot, you need to follow these steps:

Step 1: Annotate your repository interface with @Repository

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

Notice that in the above code snippet, the @Repository annotation is used above the Java interface. Notice that the UserRepository extends the CrudRepository interface? Extending CrudRepository will allow you to perform basic CREATE, READ, UPDATE and DELETE database operations. You will be able to perform these operations without writing a single SQL query.

To learn how to use Spring Data JPA with custom SQL queries, check out the following tutorials:

Step 2: Enable Spring Data JPA

For the above code snippet to compile, you will need to add Spring Data JPA dependency to a pom.xml file of your project.

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

Step 3: Configure Database Connection

@Repository annotation will help your Java class access the database and perform database-related operations. For it to work, we will need to configure database connection details in the application.properties file. Open the application.properties file of your Spring Boot project, and add the following properties:

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

The above configuration is to access the MySQL database server.  To learn how to configure the H2 in-memory database instead of MySQL, read the following tutorial: Add H2 Database to Spring Boot Project with Spring Security.

Step 4: Use Your Repository to Access Database

You can now inject a Repository into a Service class and use it to perform database-related operations. In the below code example, I use constructor-based dependency injection to inject the repository into a Service class.

@Service
public class UserService {
 
   private final UserRepository userRepository;
 
   public UserService(UserRepository userRepository) {
      this.userRepository = userRepository;
   }
 
   public List<User> getAllUsers() {
      return userRepository.findAll();
   }
 
   public User getUserById(long id) {
      return userRepository.findById(id).orElse(null);
   }
 
   public User addUser(User user) {
      return userRepository.save(user);
   }
 
   public void deleteUser(long id) {
      userRepository.deleteById(id);
   }
}

That’s it!

You have now successfully used the @Repository annotation in your Spring Boot application.

Custom Methods in Repository

While the @Repository annotation and Spring Data repositories provide a lot of functionality out of the box, there might be times when you need to perform more specific queries that aren’t covered by the standard methods. In these cases, you can define custom methods in your repository. Let’s explore how to do this.

What are Custom Repository Methods?

Custom repository methods are methods that you define in your repository interface to perform specific queries that aren’t covered by the standard methods provided by Spring Data repositories. These methods can be used to perform complex queries, filter data, or even perform calculations.

How to Define Custom Methods?

Defining custom methods in your repository is quite straightforward. You simply need to define a method signature in your repository interface, and Spring Data will automatically implement it for you.

The method name needs to follow a certain naming convention that describes the query you want to perform. Spring Data will parse the method name and create a query that matches it.

Here’s an example:

@Repository
public interface UserRepository extends CrudRepository<User, Long> {
 
   List<User> findByLastName(String lastName);
   
   List<User> findByEmailAndActive(String email, boolean active);
   
   List<User> findByActiveTrueOrderByLastNameAsc();
}

In this example, we’ve defined three custom methods:

  • findByLastName(String lastName): This method will return a list of users whose last name matches the provided string.
  • findByEmailAndActive(String email, boolean active): This method will return a list of users whose email matches the provided string and whose active status matches the provided boolean.
  • findByActiveTrueOrderByLastNameAsc(): This method will return a list of active users, ordered by their last name in ascending order.

How Does Spring Data Implement These Methods?

You might be wondering how Spring Data knows how to implement these methods. The secret is in the method names. Spring Data parses the method names and creates queries that match them.

For example, for the findByLastName(String lastName) method, Spring Data will create a query that finds users where the lastName property matches the provided string. The findBy part tells Spring Data that it needs to find records based on a certain property, and the LastName part tells it which property to use.

Similarly, for the findByEmailAndActive(String email, boolean active) method, Spring Data will create a query that finds users where the email property matches the provided string and the active property matches the provided boolean. The And part tells Spring Data that both conditions need to be true.

That’s it! You now know how to define custom methods in your Spring Data repositories. This is a powerful feature that allows you to perform complex queries without having to write any SQL or JPQL code.

Exception Translation

One of the most powerful features of the @Repository annotation is its ability to translate database-related exceptions. This is a crucial aspect to understand, especially for beginners, as it can greatly simplify error handling in your Spring Boot applications.

What is Exception Translation?

In the world of programming, an exception is an event that disrupts the normal flow of the program’s instructions. When we talk about exception translation, we are referring to the process of converting one type of exception into another.

In the context of the @Repository annotation, it translates any database-related exceptions into Spring’s DataAccessException. The DataAccessException is an unchecked exception, which means it extends the RuntimeException and you are not required to catch it.

Why is Exception Translation Important?

You might be wondering why we need to translate exceptions. The reason is simple: it provides a consistent programming model across different database technologies.

When you’re working with databases, you’ll encounter a variety of exceptions that are specific to the type of database you’re using. For example, if you’re using MySQL, you’ll get MySQL-specific exceptions. If you’re using MongoDB, you’ll get MongoDB-specific exceptions. This can make your code messy and hard to maintain, especially if you decide to switch to a different database technology in the future.

By translating these database-specific exceptions into Spring’s DataAccessException, the @Repository annotation provides a consistent, technology-agnostic model for exception handling. This means that you can catch and handle DataAccessException in your code, without worrying about the specific database technology you’re using.

How Does Exception Translation Work?

When you use the @Repository annotation, Spring automatically registers a PersistenceExceptionTranslationPostProcessor. This is a bean post-processor that adds an advisor to any bean that’s annotated with @Repository.

The advisor then adds a proxy to the @Repository bean, which intercepts and translates any database-specific exceptions into DataAccessExceptions. This happens before the exception is propagated back to your code, allowing you to handle it as a DataAccessException.

Here’s an example of how you might handle a DataAccessException in your code:

@Service
public class UserService {
 
   private final UserRepository userRepository;
 
   public UserService(UserRepository userRepository) {
      this.userRepository = userRepository;
   }
 
   public User addUser(User user) {
      try {
         return userRepository.save(user);
      } catch (DataAccessException dae) {
         // Handle the exception
         System.out.println("Error while adding user: " + dae.getMessage());
         return null;
      }
   }
}

In this example, if there’s an error while saving the user to the database, the database-specific exception is translated into a DataAccessException, which is then caught and handled in the catch block.

That’s it! You now have a basic understanding of exception translation in Spring Boot with the @Repository annotation. Remember, exception translation is a powerful feature that can help you write cleaner, more maintainable code.

Summary

In this tutorial, we’ve learned about the @Repository annotation in Spring Boot and how to use it in our applications. Here are the most important details:

  1. What is @Repository?@Repository is a Spring annotation that indicates that the decorated class is a repository. A repository is a mechanism for encapsulating storage, retrieval, and search behavior which emulates a collection of objects.
  2. How to use @Repository? – To use the @Repository annotation, you need to annotate your repository interface with @Repository. Your repository interface should extend CrudRepository or one of its subinterfaces to gain access to basic CRUD operations without writing any SQL queries.
  3. Enabling Spring Data JPA – To use @Repository, you need to enable Spring Data JPA in your project. This can be done by adding the spring-boot-starter-data-jpa dependency to your pom.xml file.
  4. Configuring Database Connection – For @Repository to work, you need to configure your database connection details in the application.properties file of your Spring Boot project.
  5. Using Repository to Access Database – Once you’ve set up your repository, you can inject it into a Service class and use it to perform database-related operations. This can be done using constructor-based dependency injection.

Remember, @Repository is just one of many stereotype annotations provided by Spring. If you’d like to learn more about other Spring’s Stereotype annotations, check out this tutorial.

Also, if you’re interested in diving deeper into Spring Data JPA and learning more about its capabilities, you can find more Spring Data JPA related tutorials here.

Thank you for reading, and happy learning!