0

I have the following repository, as simple as this:

package br.com.portal.repository;

public interface UserRepository extends CrudRepository<User, Long> {

    @Query("SELECT u FROM User WHERE u.login = :login")
    User findByLogin(@Param("login") String login);

}

Here, it's supposed to inherit all the common crud operations defined in CrudRepository and also expose the findByLogin function. Most examples, if not all, do not annotate such repository with the @Repository annotation. Why is that? Is there a need to implement this interface or does the @Query somehow does it behind the scenes?

Here is what I currently have:

package br.com.portal.service;

public interface UserService {
    User findByLogin(String login);
}

@Service
public class UserServiceImpl implements UserService {

    private UserRepository repository;

    @Autowired
    public UserServiceImpl(UserRepository repository) {
        this.repository = repository;
    }

    User findByLogin(String login) {
        return repository.findByLogin(login);
    }

}

And the spring-mvc.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/mvc
                           http://www.springframework.org/schema/mvc/spring-mvc.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/aop
                           http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- Defines the static resources location, otherwise resource requests will result in 404 errors (not found) -->
    <mvc:resources mapping="/assets/**" location="/assets/" order="0" cache-period="31556926" />
    <mvc:resources mapping="/favicon.ico" location="/assets/icon/favicon.ico" cache-period="31556926" />

    <!-- Defines the custom Spring components packages -->
    <context:component-scan base-package="br.com.portal.repository">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />
    </context:component-scan>
    <context:component-scan base-package="br.com.portal.service">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />
    </context:component-scan>
    <context:component-scan base-package="br.com.portal.controller">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <!-- JPA -->
    <bean class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean" id="entityManagerFactory">
        <property name="persistenceUnitName" value="default" />
    </bean>
    <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

</beans>

I am not using Spring Boot.

With the current above informations, we should be able to reproduce the following error:

Error creating bean with name 'userServiceImpl' defined in file xxx: Unsatisfied dependency expressed through constructor parameter 0; nested exception is NoSuchBeanDefinitionException: No qualifying bean of type 'UserRepository'

Am I missing something?

Yves Calaci
  • 1,019
  • 1
  • 11
  • 37

3 Answers3

1

Spring is telling you there's no bean named 'userServiceImpl', which looks correct. That text (case sensitive) doesn't exist. You should look at how to name the bean. You might just need to provide a name in the @Service annotation.

  • That bean IS correct. If you read my comments, you would have seen that it does work if I implement the `UserRepository` interface. That means that Spring is not recognizing that repository as one. – Yves Calaci Nov 25 '17 at 13:02
1

You need to tell spring to scan for repository interfaces to provide implementations for. With XML you do this by adding the namespace:

xmlns:jpa="http://www.springframework.org/schema/data/jpa"

to the beans tag and then include this line

<jpa:repositories base-package="br.com.portal.repository"/>

inside. See this answer for more context.

You DO NOT NEED a @Repository annotation on your interface. That basically comes implicitly from extending CrudRepository

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
  • Thanks, @Jens. I was going to answer my own question but you did it first. It took me a while to find out. Also, please update your answer to include the Spring Data version `1.9.0.RELEASE` in the `pom.xml`. The lastests versions throws an AbstractMethodError (according to some stackoverflow answer, it's related to a conflict between the versions/dependencies of `spring-data-jpa` and `spring-data-commons` jars). – Yves Calaci Nov 27 '17 at 12:05
  • Not sure what you mean. Neither you nor I am referencing the pom, nor seems it relevant to the question. Do you have a link to this discussion of the version conflict you mentioned? – Jens Schauder Nov 27 '17 at 12:32
  • I have a Maven project and the above samples (including your answer) only work with `Spring Data 1.9.0.RELEASE`. If I use the lastest version (2.0.2.RELEASE), it crashes with the following error: `org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Initialization of bean failed; nested exception is java.lang.AbstractMethodError`. I couldnt find the discussions anymore btw – Yves Calaci Nov 29 '17 at 14:12
  • Mixing spring-data-jpa and spring-data-commons from different release trains will cause problems. But spring-data-jpa should (and I'm pretty sure it does) come with the proper transitive dependencies. So this should work in 2.x just as well. If it doesn't you can always open another question. Make sure to include the full stack trace. – Jens Schauder Nov 29 '17 at 15:26
  • `spring-data-jpa` comes with `spring-data-commons`. I'm referencing only the `spring-data-jpa` version `2.0.2.RELEASE` in my `pom.xml` but it causes the above exception when starting the app. However, if the version is changed to `1.9.0.RELEASE`, everything works. – Yves Calaci Nov 29 '17 at 16:50
  • Here's the new question: https://stackoverflow.com/questions/47558017/error-starting-a-spring-application-initialization-of-bean-failed-nested-excep – Yves Calaci Nov 29 '17 at 17:03
-1

Annotate the UserRepository interface with @Repository

Mustapha Belmokhtar
  • 1,231
  • 8
  • 21