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:
- Spring Data JPA Native SQL Query,
- Spring Data JPA Native UPDATE SQL Query,
- Spring Boot REST and JPA – Save to a Database
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:
- 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. - How to use
@Repository
? – To use the@Repository
annotation, you need to annotate your repository interface with@Repository
. Your repository interface should extendCrudRepository
or one of its subinterfaces to gain access to basic CRUD operations without writing any SQL queries. - Enabling Spring Data JPA – To use
@Repository
, you need to enable Spring Data JPA in your project. This can be done by adding thespring-boot-starter-data-jpa
dependency to yourpom.xml
file. - Configuring Database Connection – For
@Repository
to work, you need to configure your database connection details in theapplication.properties
file of your Spring Boot project. - 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!