8

I have packaged my entire entities of the application and the repository interfaces into one jar. The repositories are written with @Repository annotation:

@Repository
public interface InternalUserRepository extends JpaRepository<InternalUser, Long>{

}

I have included this jar file inside my spring boot application and trying to autowire the interface like this from a controller:

@RestController
public class AuthenticationController {

    @Autowired
    AuthenticationService authenticationService;

    @Autowired
    InternalUserRepository internalUserRepository;


    @GetMapping("/")
    public String home() {
        return "Hello World!";
    }

}

My Main app class is written like:

@SpringBootApplication
@EnableJpaRepositories
@ComponentScan("com.cdac.dao.cdacdao.*")
public class CdacAuthenticationMgntApplication {

public static void main(String[] args) {
    SpringApplication.run(CdacAuthenticationMgntApplication.class, args);
}
}

The repository is not getting autowired. When I am firing up the Spring boor application I am getting the following error:

***************************
APPLICATION FAILED TO START
***************************

Description:

Field internalUserRepository in 
com.cdac.user.cdacauthenticationmgnt.controller.AuthenticationController required a bean of type 'com.cdac.dao.cdacdao.repository.InternalUserRepository' that could not be found.


Action:

Consider defining a bean of type 'com.cdac.dao.cdacdao.repository.InternalUserRepository' in your configuration.

Have anyone tried similar architecture like this?

deDishari
  • 187
  • 1
  • 3
  • 11
  • What package is the `InternalUserRepository` interface defined in? Also, try removing the `.*` at the end of the scanned packages... `@ComponentScan("com.cdac.dao.cdacdao")` – ptomli May 08 '18 at 10:13
  • Possible duplicate of [SpringBoot ComponentScan issue with multi-module project](https://stackoverflow.com/questions/30587377/springboot-componentscan-issue-with-multi-module-project) – Herr Derb May 08 '18 at 10:16

3 Answers3

12

If your JPA repositories are in a different package than your Spring Boot application class, you have to specify that package on the EnableJpaRepositories annotation, not Component:

@EnableJpaRepositories("com.cdac.dao.cdacdao")

The package you specified on ComponentScan is for detecting classes as regular Spring beans, not repository interfaces.

dunni
  • 43,386
  • 10
  • 104
  • 99
-1

As I remember, @ComponentScan should take a complete path to a package, so I think that your package.* does not work.

Try to use type-safe component scan instead:

// You refer to your packages of your base project and your module here. 
// Choose the class so that their package is cover all child package
@SpringBootApplication(scanBasePackageClasses = {xxx. InternalUserRepository.class, xxx.CdacAuthenticationMgntApplication.class}) 

@EnableJpaRepositories
// No need to explicit @ComponentScan
public class CdacAuthenticationMgntApplication {

Or you can try @EnableJpaRepositories("com.cdac.dao.cdacdao")

Either way, you should pick the class in the most outer package (Spring will aslo try to find bean in sub package of those component scan packages)

Mạnh Quyết Nguyễn
  • 17,677
  • 1
  • 23
  • 51
  • In this case you can also skip `@EnableJpaRepositories`, because that's also part of the `@SpringBootApplication` functionality. – dunni May 08 '18 at 10:17
  • I really don't know that. Could you please give me a reference? Thanks for sharing :D – Mạnh Quyết Nguyễn May 08 '18 at 10:19
  • 1
    It's done by the Spring Data autoconfiguration: https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfiguration.html: `Once in effect, the auto-configuration is the equivalent of enabling JPA repositories using the EnableJpaRepositories annotation.` – dunni May 08 '18 at 10:20
  • The solution will work if my Repository classes are in the same project,i.e., the spring boot application I am developing. In my case, the repositories are part of an external jar which is included as part of the dependencies. Do I need to unpack the jar? – deDishari May 08 '18 at 10:47
  • That's why you need to refer your repository class in `@ComponentScan` or use package string. – Mạnh Quyết Nguyễn May 08 '18 at 10:48
  • MạnhQuyếtNguyễn you mean like this: @ComponentScan({"com.cdac.dao.cdacdao","com.cdac.user.cdacauthenticationmgnt"}) – deDishari May 08 '18 at 10:52
  • Yes. Just add the package of your repository there. But I recommend you to use class to avoid typo – Mạnh Quyết Nguyễn May 08 '18 at 10:54
  • tried Both way(With and without class). Seems not working. The same error is coming back – deDishari May 08 '18 at 10:56
  • Have you tries this: @EnableJpaRepositories("com.cdac.dao.cdacdao") – Mạnh Quyết Nguyễn May 08 '18 at 10:57
  • Yep. the same output. I guess I don't need to put the package in @Componentscan if I am using @EnableJpaRepositories("") – deDishari May 08 '18 at 11:01
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/170608/discussion-between-dedishari-and-mnh-quyt-nguyn). – deDishari May 08 '18 at 11:04
  • I think I can help you via teamview later. Now I have to go to the airpot. But try to figure yourself first, just need to declare the correct package to your @componentscab – Mạnh Quyết Nguyễn May 08 '18 at 11:06
  • Okay let me try out further. We can catch up when you have time. I will update here if I get to find the solution – deDishari May 08 '18 at 11:29
-1

Annotation @SpringBootApplication has supported all function So we don't need config manually

@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
Phuoc Huynh
  • 692
  • 4
  • 7