7

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?

Snackoverflow
  • 5,332
  • 7
  • 39
  • 69

3 Answers3

6

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

RamiReddy P
  • 1,628
  • 1
  • 18
  • 29
  • Conclusion: The usefulness of this annotation is that I can handle all `DataAccessException`s differently to a general `Throwable` type? – Snackoverflow Apr 17 '19 at 13:57
  • Yes, check https://www.logicbig.com/tutorials/spring-framework/spring-data-access-with-jdbc/data-access-exception.html – RamiReddy P Apr 17 '19 at 14:00
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.

SCRE
  • 31
  • 1
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

Community
  • 1
  • 1
balag3
  • 665
  • 5
  • 8
  • 1
    There doesn't seem to be a `@Repository` annotation in the inheritance hierarchy of `CrudRepository` or `JpaRepository`. – Snackoverflow Apr 17 '19 at 13:49