Spring @ComponentScan doesn't work on @Repository
Asked Answered
B

3

8

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

Bedroom answered 6/11, 2018 at 12:53 Comment(8)
If you extend from Spring repositories to use basic CRUD operations , you need to enable them via @EnableJPARepositories in order the springboot to detect and initialize the implementations of them at runtime.Kazue
@TürkmenMustafaDemirci aaah you mean if I make my own repository it will work ?Bedroom
I guess it should work without @enableJPARepositories . give it a try and please tell us about the result I also wondered.Kazue
@TürkmenMustafaDemirci it didnt work thats why I post the question, the code like above doesnt workBedroom
please check if you have any "spring.autoconfigure.exclude" param inside application.propertiesUndies
@MohammadRezaAlagheband I don't haveBedroom
@MohammadKarmi i suggest you to create a package like com.app.repository and move your repository class there, then add @EnableJpaRepositories("com.app.reporsitory") on the runner.Undies
@MohammadRezaAlagheband again I know the solution and it will work, but Im asking for an explanationBedroom
B
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) {

             .......
    }
}
Bedroom answered 6/11, 2018 at 13:49 Comment(0)
M
12

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).

Mccallum answered 6/11, 2018 at 13:3 Comment(5)
I know this is the solution, but is that expected ? in the documentation they say @ ComponentScan work on @ RepositoryBedroom
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 ?Bedroom
nothing is needed if you follow the golden words in my answer only @SpringBootApplication is enoughMccallum
you are totally right. but I was curious about this :) . see my updated questionBedroom
I did and here what they say : Indicates whether automatic detection of classes annotated with @ Component @ Repository, @ Service, or @ Controller should be enabled.Bedroom
B
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) {

             .......
    }
}
Bedroom answered 6/11, 2018 at 13:49 Comment(0)
M
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 {
    }
Menides answered 6/11, 2018 at 12:58 Comment(9)
this doesn't answer the question. the repository is outside com.app . I'm asking why enablejparepositories is neededBedroom
can you please try this approachMenides
if you are doing any crud operation then you have to use jpa dependency and for that you have to enable @EnableJPARepositoriesMenides
@ EnableJPARepositories scan the package you have in your configuration class. I know the solution which is same as @Mccallum mentioned , I already said the solution in question. I'm asking about the reason not the solutionBedroom
@MohammadKarmi please refer 3rd comment, it's a springboot functionality you have to EnableJPARepositories for any JpaRepository operation.Menides
@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.Menides
that's correct but for @ Repository I don't see any benefit with componenetscanBedroom
@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.Menides
@Guarav actually it will , I tried with enablejparepositories only and it worked.Bedroom

© 2022 - 2024 — McMap. All rights reserved.