Clarification about @EnableMongoRepositories

Alex picture Alex · Oct 16, 2014 · Viewed 11.3k times · Source

I'm trying to use @EnableMongoRepositories for using two separate mongo repositories like:

@Configuration
@EnableMongoRepositories(mongoTemplateRef = "mongoBOTemplate", basePackages = "sandbox.dao.bo")
public class BOMongoConfig {

    @Value("#{mongo.hostBO}")
    private String hostBO;

    @Value("#{mongo.databaseBO}")
    private String databaseBO;

    @Bean
    public MongoDbFactory mongoBODbFactory() throws Exception {
        return new SimpleMongoDbFactory(new MongoClient(hostBO), databaseBO);
    }

    @Bean
    public MongoTemplate mongoBOTemplate() throws Exception {
        return new MongoTemplate(mongoBODbFactory());
    }
}

and

@Configuration
@EnableMongoRepositories(mongoTemplateRef = "mongoTemplate", basePackages = "sandbox.dao.sandbox")
public class SandboxMongoConfig {

    @Value("#{mongo.host}")
    private String host;

    @Value("#{mongo.database}")
    private String database;

    @Bean
    public MongoDbFactory mongoDbFactory() throws Exception {
        return new SimpleMongoDbFactory(new MongoClient(host), database);
    }

    @Bean
    public MongoTemplate mongoTemplate() throws Exception {
        return new MongoTemplate(mongoDbFactory());
    }
}

but I'm confused because of this error:

710  [RMI TCP Connection(2)-127.0.0.1] ERROR org.springframework.web.servlet.DispatcherServlet  - Context initialization failed
java.lang.IllegalArgumentException: Environment must not be null!
    at org.springframework.util.Assert.notNull(Assert.java:112)
    at org.springframework.data.repository.config.RepositoryConfigurationSourceSupport.<init>(RepositoryConfigurationSourceSupport.java:50)
    at org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource.<init>(AnnotationRepositoryConfigurationSource.java:74)
    at org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport.registerBeanDefinitions(RepositoryBeanDefinitionRegistrarSupport.java:74)
    at org.springframework.context.annotation.ConfigurationClassParser.processImport(ConfigurationClassParser.java:340)
    at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:233)
    at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:154)
    at org.springframework.context.annotation.ConfigurationClassParser.processImport(ConfigurationClassParser.java:349)
    at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:233)
    at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:154)
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:140)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:282)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:223)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:630)

As I understood there is only one option to fix it is using @Profile. I'm using maven to profile management and not sure why I need hardcore profiles in code...

Could anyone help me with misunderstanding? Thanks.

Answer

freakman picture freakman · Oct 16, 2014

Well, you have to somehow show spring which of those configurations to use for particular case. Otherwise how would it be possible decide which MongoDbFactory instance to create? So yes, use @Profile above both @Configuration classes.

Also please note that maven profiles are not spring profiles. Might be that you dont have to mix maven into that ( if maven profile is only use to set spring one ). I such case you can add -Dspring.profiles.active=profile while running your app.