Spring Boot автоматически генерирует таблицы из неверного источника данных - PullRequest
0 голосов
/ 31 мая 2018

Мой текущий проект должен подключиться к нескольким базам данных.Я установил

spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update

в application.properties .

и у меня есть некоторые dbConfig, как показано ниже:

@Configuration
public class DBSourceConfiguration {
    public final static String DATA_SOURCE_PRIMARY = "dataSource";
    public final static String DATA_SOURCE_PROPERTIES = "propertiesDataSource";
    public final static String DATA_SOURCE_REPORT = "reportDataSource";
    public final static String DATA_SOURCE_NEW_DRAGON = "newDragonDataSource";

    @Primary
    @Bean(name = DATA_SOURCE_PRIMARY)
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = DATA_SOURCE_REPORT)
    @ConfigurationProperties(prefix = "externaldatasource.report")
    public DataSource reportDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = DATA_SOURCE_NEW_DRAGON)
    @ConfigurationProperties(prefix = "externaldatasource.newdragon")
    public DataSource newDragonDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = DATA_SOURCE_PROPERTIES)
    @ConfigurationProperties(prefix = "externaldatasource.properties")
    public DataSource propertiesDataSource() {
        return DataSourceBuilder.create().build();
    }
}

и

<!-- language: Java -->

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = PrimaryDbConfig.ENTITY_MANAGER_FACTORY, 
            transactionManagerRef = PrimaryDbConfig.TRANSACTION_MANAGER, 
            basePackageClasses = { _TbsRepositoryBasePackage.class })
    public class PrimaryDbConfig extends AbstractDbConfig {
        public final static String ENTITY_MANAGER_FACTORY = "entityManagerFactoryPrimary";
        public final static String ENTITY_MANAGER = "entityManagerPrimary";
        public final static String TRANSACTION_MANAGER = "transactionManagerPrimary";

        @Autowired
        @Qualifier(DBSourceConfiguration.DATA_SOURCE_PRIMARY)
        private DataSource dataSource;

        @Primary
        @Bean(name = ENTITY_MANAGER_FACTORY)
        public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
            return builder.dataSource(dataSource).properties(getVendorProperties(dataSource)).packages(_TbsEntityBasePackage.class).persistenceUnit("primaryPersistenceUnit").build();
        }

        @Primary
        @Bean(name = ENTITY_MANAGER)
        public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
            return entityManagerFactory(builder).getObject().createEntityManager();
        }

        @Primary
        @Bean(name = TRANSACTION_MANAGER)
        public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
            return new JpaTransactionManager(entityManagerFactory(builder).getObject());
        }    
    }

и

<!-- language: Java -->

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = PropertiesDbConfig.ENTITY_MANAGER_FACTORY, 
            transactionManagerRef = PropertiesDbConfig.TRANSACTION_MANAGER, 
            basePackageClasses = { _PropertiesRepositoryBasePackage.class })
    public class PropertiesDbConfig extends AbstractDbConfig {
        public final static String ENTITY_MANAGER_FACTORY = "entityManagerFactoryProperties";
        public final static String ENTITY_MANAGER = "entityManagerProperties";
        public final static String TRANSACTION_MANAGER = "transactionManagerProperties";

        @Autowired
        @Qualifier(DBSourceConfiguration.DATA_SOURCE_PROPERTIES)
        private DataSource dataSource;

        @Bean(name = ENTITY_MANAGER_FACTORY)
        public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
            return builder.dataSource(dataSource).properties(getVendorProperties(dataSource)).packages(_PropertiesEntityBasePackage.class).persistenceUnit("propertiesPersistenceUnit").build();
        }

        @Bean(name = ENTITY_MANAGER)
        public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
            return entityManagerFactory(builder).getObject().createEntityManager();
        }

        @Bean(name = TRANSACTION_MANAGER)
        public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
            return new JpaTransactionManager(entityManagerFactory(builder).getObject());
        }
    }

и еще два класса DBConfig (простокак два вышеописанных класса DbConfig).

Моя проблема заключается в том, что каждый раз, когда я запускаю это веб-приложение, сущности (в разных пакетах) генерируют все базы данных.Другими словами, объекты Tbs (Primary) будут генерировать таблицы для newDragon и всех других баз данных.

Например, объект A принадлежит первичному источнику данных, объект B принадлежит свойств данных .Но Framework генерирует таблицу A, B для обеих первичных баз данных и newDragon базы данных и двух других баз данных .


Обновление 2018/06/01 - 1

Хотя Framework генерирует все сущности для всех баз данных, но я все еще могу получить доступ к таблицам из нужной базы данных.Все функции моего веб-приложения работают очень хорошо.Это очень странно, не правда ли?

Полагаю, моя конфигурация в порядке, так что никаких проблем при работе с базой данных моего приложения нет (например, чтение из неправильной базы данных и получение пустого результата или вставка данных в неправильную базу данных и т. Д.).Вероятно, что-то еще вызывает эту проблему все таблицы для всех баз данных.

1 Ответ

0 голосов
/ 01 июня 2018

Исходя из предоставленной вами конфигурации, таблицы CRUD из правильной базы данных не должны быть проблемой.Но, генерируя таблицы в нужной базе данных, иногда вы можете проверить, правильно ли конфигурация выбирает имена сущностей / пакетов или нет.

Каждому LocalContainerEntityManagerFactoryBean присваивается уникальный класс пакета, затем инфраструктура будет сканировать объекты под этим именем пакета и соответственно генерировать таблицы на целевом источнике данных;Однако есть ситуация, когда пакет ToScan будет изменен.Поскольку у вас есть аннотация @EntityScan, она
переопределяет PackageToScan для всех определенных LocalContainerEntityManagerFactoryBean, ссылочный код выглядит следующим образом: EntityScanRegistrar.java

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    if (bean instanceof LocalContainerEntityManagerFactoryBean) {
        LocalContainerEntityManagerFactoryBean factoryBean = (LocalContainerEntityManagerFactoryBean) bean;
        factoryBean.setPackagesToScan(this.packagesToScan);
        this.processed = true;
    }
    return bean;
}

В результате даже вы предоставиликаждый LocalContainerEntityManagerFactoryBean с уникальным классом пакета, итоговый результат все равно может быть переопределен платформой, если вы где-то в своем приложении @EntityScan.Мне кажется, что ваша конфигурация в порядке, поэтому попробуйте сначала найти и разрешить имена пакетов между @EntityScan и LocalContainerEntityManagerFactoryBean, это должно решить проблему.

ссылка: https://github.com/spring-projects/spring-boot/issues/6830

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...