When to use Spring's @Repository annotation?
Asked Answered
W

3

8

When reading about creating custom queries in Spring, I noticed that none of the classes (UserRepositoryCustom, UserRepositoryCustomImpl, UserRepository) use the @Repository annotation.

I was surprised by this, because usually all the Spring application classes are annotated by something for them to be detected and a proxy generated for them. That's how the aspect-oriented framework works in Java.

Then I checked my old working code, and realized that my repository interface also does not use the annotation. Yet, it is @Autowired as a dependency into the controllers and other classes that use it. Example:

// AddressRepository.java
public interface AddressRepository extends CrudRepository<Address, String> {
}

// Repositories.java
@Getter // lombok
@Component
public class Repositories { // autowire this to have access to all repo's
    private final AddressRepository addressRepository;

    @Autowired
    public Repositories(AddressRepository addressRepository) {
        this.addressRepository = addressRepository;
    }
}

This begs the questions: When should the annotation be used? and How come a non-annotated class is automatically detected by Spring's component scan?

Walloper answered 17/4, 2019 at 13:26 Comment(4)
do you have an example?Emirate
Check out this question #44069867Regale
@Regale Thanks, it answers the second half of my question.Walloper
@MarkusG. edited to add the exampleWalloper
A
8

It activates persistence exception translation for all beans annotated with @Repository, to let exceptions being thrown by the JPA persistence providers be converted into Spring’s DataAccessException hierarchy.

That Means all un checked exceptions thrown in that class will be converted to DataAccessException.

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.create-instances

Aggravate answered 17/4, 2019 at 13:36 Comment(2)
Conclusion: The usefulness of this annotation is that I can handle all DataAccessExceptions differently to a general Throwable type?Walloper
Yes, check logicbig.com/tutorials/spring-framework/…Aggravate
J
3

@Autowired asks the Spring IoC-Container for an object of type AddressRepository. Being an interface, it can't be instantiated, therefore there has to be an implementation.

org.springframework.data.jpa.repository.support.SimpleJpaRepository is that implementation:

@Repository
@Transactional(readOnly = true)
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {

and here you see the @Repository annotation, which acts as a specialization for @Component.

Jochebed answered 19/5, 2020 at 21:7 Comment(0)
T
1

Extending org.springframework.data.repository.Repository interface marks the subclasses for bean creation.
In your case the inheritance looks the following:
YourRepository -> JpaRepository -> PagingAndSortingRepository -> CrudRepository -> org.springframework.data.repository.Repository
According the documentation:
General purpose is to hold type information as well as being able to discover interfaces that extend this one during classpath scanning for easy Spring bean creation.
Source: Interface Repository

Tobytobye answered 17/4, 2019 at 13:35 Comment(1)
There doesn't seem to be a @Repository annotation in the inheritance hierarchy of CrudRepository or JpaRepository.Walloper

© 2022 - 2024 — McMap. All rights reserved.