6

I have a repository in different package than the configuration class , so I annotated it as the following with @Repostiory:

package test;

@Repository
public interface UserTest extends JpaRepository<User, Long> {
}

I have done the component scan on it and it didn't work :

package com.app;
@SpringBootApplication
@ComponentScan({"test","com.app"})
public class Application extends SpringBootServletInitializer {
}

Exception : No qualifying bean of type 'test.UserTest' available: expected at least 1 bean which qualifies as autowire candidate.

why doesn't the component scan work on repository unless I add enableJpaRepositories ? I thought componetScan is enough


Update:

as some of the answers provides solution , I'm asking about explanation not solution . The following will work without even doing component scan on "test" :

SpringBootApplication
@EnableJpaRepositories({"test","com.app"})
public class Application extends SpringBootServletInitializer{
}

Now the question why do I even need to use componentscan on @Repository when it doesn't work ? why in the documentation the @Repository is scanned by componentscan when it doesnt have effect and @EnableJpaRepostiories is enoguh?

from Spring documentation on component scan : Indicates whether automatic detection of classes annotated with @Component @Repository, @Service, or @Controller should be enabled.

the @Repository in my case is not detected

Mohammad Karmi
  • 1,403
  • 3
  • 26
  • 42

3 Answers3

9

In order to let spring knows what DataSource is related to what Repository you should define it at the @EnableJpaRepositories annotation.

Try enabling jpa repositories like below.

@SpringBootApplication
@ComponentScan({"test","com.app"})
@EnableJpaRepositories("test")
public class Application extends SpringBootServletInitializer {
}

UPDATE : Why @EnableJpaRepositories needed?

@SpringBootApplication automatically provides the features of the following annotations

@Configuration @EnableAutoConfiguration @ComponentScan

But if you try defining your own annotation then spring boot will not take care of internal auto configurations so this is the reason we have to enable repositories.

I have projects in which only @SpringBootApplication is enough if you are not writing your own things.

I hope you got the point.

Golden words :

If you want to get the maximum advantage of spring boot’s auto configuration feature, it is expected to put all your class packages under spring boot main application package (directly in main package or indirectly as sub packages).

Alien
  • 15,141
  • 6
  • 37
  • 57
  • I know this is the solution, but is that expected ? in the documentation they say @ ComponentScan work on @ Repository – Mohammad Karmi Nov 06 '18 at 13:05
  • Thanks for the answer Alien, yes that's right I know spring boot provide the above 3 annotations. but the main question here , if enableJpaReposiotry is enough why do I need componentScan on @Repository if it doesnt work at all ? – Mohammad Karmi Nov 06 '18 at 13:14
  • nothing is needed if you follow the golden words in my answer only @SpringBootApplication is enough – Alien Nov 06 '18 at 13:17
  • you are totally right. but I was curious about this :) . see my updated question – Mohammad Karmi Nov 06 '18 at 13:19
  • I did and here what they say : Indicates whether automatic detection of classes annotated with @ Component @ Repository, @ Service, or @ Controller should be enabled. – Mohammad Karmi Nov 06 '18 at 13:30
2

I found an explanation about what I was doing wrong. The @Repository annotation with componentscan will not cause spring to implement the spring jpa repository. for the interfaces that implement crud repository enablejparepository should be used.

Now the use of @Repository with componentscan is when you have a repository class and you have your own DAO not for spring curd repo otherwise the implementation won't be created :

@Repository
public class UserTest {


    public List<Object> findById(long l) {

             .......
    }
}
Mohammad Karmi
  • 1,403
  • 3
  • 26
  • 42
0

you should use your code like below as @ComponentScan always work with basepackages so your implementation should be like below.

 package com.app;
    @SpringBootApplication
    @ComponentScan(basePackages={"test","com.app"})
    @EnableJPARepositories 
    public class Application extends SpringBootServletInitializer {
    }
GauravRai1512
  • 834
  • 6
  • 14
  • this doesn't answer the question. the repository is outside com.app . I'm asking why enablejparepositories is needed – Mohammad Karmi Nov 06 '18 at 13:00
  • can you please try this approach – GauravRai1512 Nov 06 '18 at 13:05
  • if you are doing any crud operation then you have to use jpa dependency and for that you have to enable @EnableJPARepositories – GauravRai1512 Nov 06 '18 at 13:07
  • @ EnableJPARepositories scan the package you have in your configuration class. I know the solution which is same as @Alien mentioned , I already said the solution in question. I'm asking about the reason not the solution – Mohammad Karmi Nov 06 '18 at 13:07
  • @MohammadKarmi please refer 3rd comment, it's a springboot functionality you have to EnableJPARepositories for any JpaRepository operation. – GauravRai1512 Nov 06 '18 at 13:15
  • @MohammadKarmi As per my understanding and also i have created few project on spring-boot application where i have seen that if you are not mentioning componentcsan on main class. your controller, service class etc would not execute so to find the controller class and services repositories etc you have to provide the package details otherwise main class would not able to find the classes also EnableJpaRepositiories is for to enable jpa crud operation. – GauravRai1512 Nov 06 '18 at 13:38
  • that's correct but for @ Repository I don't see any benefit with componenetscan – Mohammad Karmi Nov 06 '18 at 13:41
  • @MohammadKarm Yes, but Repository is in test package so if you will not provide the package details in componentscan. main boot class would not be able to find Repository class so as per my understanding you should mention the package details of Repository. – GauravRai1512 Nov 06 '18 at 13:45
  • @Guarav actually it will , I tried with enablejparepositories only and it worked. – Mohammad Karmi Nov 06 '18 at 13:46