SpringBoot направляет MongoRepository в конкретный MongoTemplate - PullRequest
0 голосов
/ 29 июня 2018

У меня есть приложение с несколькими конфигурациями монго. Это достигается с помощью некоторых классов @Configuration, таких как

public abstract class AbstractMongoConfig {
    private String database;
    private String uri;

    public void setUri(String uri) {
        this.uri = uri;
    }

    public void setDatabase(String database) {
        this.database = database;
    }

    public MongoDbFactory mongoDbFactory() throws Exception {
        return new SimpleMongoDbFactory(new MongoClient(new MongoClientURI(this.uri)), this.database);
    }

    abstract public MongoTemplate getMongoTemplate() throws Exception;
}

Конфиг 1 - приложение

@Configuration
@ConfigurationProperties(prefix="app.mongodb")
public class AppMongoConfig extends AbstractMongoConfig {
    @Primary
    @Override
    @Bean(name="appMongoTemplate")
    public MongoTemplate getMongoTemplate() throws Exception {
        return new MongoTemplate(mongoDbFactory());
    }
}

Конфиг 2 - тест

@Configuration
@ConfigurationProperties(prefix="test.mongodb")
public class TestMongoConfig extends AbstractMongoConfig {
    @Override
    @Bean(name="testMongoTemplate")
    public MongoTemplate getMongoTemplate() throws Exception {
        return new MongoTemplate(mongoDbFactory());
    }
}

Тогда в моих свойствах

test.mongodb.uri=mongodb://127.0.0.1/test
test.mongodb.database=test
app.mongodb.uri=mongodb://127.0.0.1/app
app.mongodb.database=app

Итак, два конфига mongo подключены к экземпляру, работающему локально, но с разными базами данных. Я пробовал и с другими адресами, но он ведет себя одинаково.

В любом случае, это затем используется через Entity и MongoRepository

@Document(collection="collname")
public class TestObj {

    @Id
    private String id;

    private String username;
    private int age;
    // getters & setters
}

Repo

@Repository
public interface TestObjRepository extends MongoRepository<TestObj, String> {
    public TestObj findByUsername(String username);
}

Однако, когда я использую это в каком-то классе

@Service
public class ThingDoer {

    @Autowired
    TestObjRepository toRepo;

    public void doStuff() {
        TestObj to = new TestObj("name", 123);
        toRepo.save(to);
    }
}    

Этот объект записывается в TestMongoConfig, а не AppMongoConfig, как я и ожидал, поскольку этот объект помечен @Primary. Кроме того, если я добавлю аннотацию @EnableMongoRepositories в ThingDoer, например:

@EnableMongoRepositories(basePackages={"com.whatever.package"}, mongoTemplateRef="appMongoTemplate")

Это все еще не работает. Он по-прежнему записывает в базу данных, на которую ссылается «test».

Если я @Autowire в MongoTemplate напрямую и использую это, он работает как я ожидаю. Дела идут в «приложение» репо. Как я могу сказать ему, какая база данных, в которую TestObjRepository должен записывать и читать?

1 Ответ

0 голосов
/ 26 февраля 2019

Итак, если у кого-то еще есть эта проблема, решение таково:

@EnableMongoRepositories(basePackages={"com.whatever.package"}, mongoTemplateRef="appMongoTemplate")

Вы должны поставить его на свои свойства монго. Где basePackages - это путь к вашему репо. У вас должен быть один пакет для каждой базы данных mongo, поэтому он ищет предполагаемый репозиторий и ссылку на модель. Также вам необходимо отключить автоматическую настройку Монго весной, когда используется несколько БД:

spring.autoconfigure.exclude:org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration

Это отличный учебник: https://dzone.com/articles/multiple-mongodb-connectors-with-spring-boot

...