0

I'm trying to load beans from a different package on a Spring boot application. Here's my main class, that lives in com.xyz.app package:

Application.java:

@SpringBootApplication(scanBasePackages = { "com.xyz.app.repository" })
public class Application extends SpringBootServletInitializer {

 @Override
 protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(Application.class);
 }

 public static void main(String[] args) {
    ConfigurableApplicationContext context = 
                            SpringApplication.run(Application.class, args);

    context.getBean(MyInterfaceRepository.class).loadData();
 }

The interface MyInterfaceRepository.java is inside the com.xyz.app.repository package, and is defined as follows:

@RepositoryRestResource(collectionResourceRel = "aas", path = "aas")
public interface MyInterfaceRepository extends MongoRepository<MyClass, Long>, 
                                                 MyCustomInterface {
  ...
}

Then, I also have a MyInterfaceRepositoryImpl.java, that lives in com.xyz.app.repository, that provides an implementation for MyCustomInterface.java, that also lives in com.xyz.app.repository.

Starting my application I get the following:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xyz.app.repository.MyInterfaceRepository] is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:372)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:332)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1066)
    at com.xyz.app.Application.main(Application.java:60)

I already checked, and indeed if I put MyInterfaceRepository.java and MyInterfaceRepositoryImpl.java in the same package as Application.java, com.xyz.app, than it works.

It seems that Spring is not able to load the beans from a different package than the one where Application.java is.

Also, I tried replacing the @SpringBootApplication with these:

@Configuration
@EnableAutoConfiguration
@ComponentScan({"com.xyz.app.repository"})

Same issue.. Any idea?

nmpg
  • 561
  • 2
  • 10
  • 24
  • subpackages are automatically scanned so anything that's under `com.xyz.app` would work. Just remove the custom declaration. – Stephane Nicoll Jul 07 '16 at 08:27
  • Why do you even have an implementation? You are using Spring Data so the isn't needed – M. Deinum Jul 07 '16 at 08:34
  • Do you actually have `spring-boot-starter-data-mongo` dependency? – M. Deinum Jul 07 '16 at 08:46
  • I have an implementation because I need it for my custom method defined in MyCustomInterface. Essentially, I do as described here: http://stackoverflow.com/questions/17008947/whats-the-difference-between-spring-datas-mongotemplate-and-mongorepository – nmpg Jul 07 '16 at 08:47
  • And yes, I do have spring-boot-starter-data-mongo – nmpg Jul 07 '16 at 08:48
  • Are there any other exceptions? When you add `scanBasePackages` explicitly, it will only scan the packages listed. So other classes like configuration may not be scanned. Try to replace the package with the root package and see if it works. – grape_mao Jul 07 '16 at 09:37
  • I also have another Exception in thread "main" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException. Alas, changing the package does not seem to help – nmpg Jul 07 '16 at 12:52

2 Answers2

0

if you are using spring mongodb, you don't need to use annotation: @RepositoryRestResource(collectionResourceRel = "aas", path = "aas")

You also can use @Autowired in the MyInterfaceRepository.

Sergio
  • 3,317
  • 5
  • 32
  • 51
NguaCon
  • 124
  • 9
  • Well, if I do this then I need to provide an implementation for all MongoRepository methods.. – nmpg Jul 07 '16 at 09:04
  • You don't need to do that. Please try using it. – NguaCon Jul 07 '16 at 09:15
  • I did, I put @Autowired before _public interface ... _ and it asks me for an implementation of all MongoRepository methods in some class.. – nmpg Jul 07 '16 at 09:22
  • Why should he use Autowired in the interface? The interface doesn't have any fields which could be autowired, so this doesn't make any sense. – dunni Jul 07 '16 at 12:10
  • you use something like that `public interface YourRepository extends CrudRepository`. You can `@Autowire YourRepository` anywhere because spring framework had implemented the interface. – NguaCon Jul 08 '16 at 02:34
0

On your application class/main class add @EnableMongoRepositories. You should have something like this:

@SpringBootApplication(scanBasePackages = {"com.xyz.app"})
@EnableMongoRepositories(basePackages = {"com.xyz.app.repository"}, repositoryBaseClass = MyInterfaceRepositoryImpl.class)
public class Application extends SpringBootServletInitializer {
    ...
}

See EnableMongoRepositories for more details about the annotation.

Rae Burawes
  • 892
  • 7
  • 18