Spring Boot中的多数据源和模式创建

36

我正在使用Spring Boot。我最终设法设置了两个数据源,但现在我面临另一个问题。

  1. 当有两个数据源时,spring.jpa.hibernate.ddl-auto=create在我的Spring Boot应用程序中似乎不起作用,只有spring.jpa.generate-ddl=true才能完成工作。
  2. 我无法为每个数据源选择自动创建策略。我希望为数据源一创建模式,并在第二个数据源(数据源二)中使用所创建的模式。

有人知道如何解决这些问题吗?请注意,如果可能,我不想完全放弃自动配置。我甚至还不知道,Hibernate是否能够只初始化一个持久化单元的模式。

application.properties

spring.datasource-internal.url=jdbc:hsqldb:mem:testdb
spring.datasource-internal.username=sa
spring.datasource-internal.password=sa
spring.datasource-internal.driver-class-name=org.hsqldb.jdbcDriver
spring.datasource-internal.jpa.database-platform=org.hibernate.dialect.HSQLDialect

spring.datasource-external.url=jdbc:hsqldb:mem:testexternal
spring.datasource-external.username=sa
spring.datasource-external.password=sa
spring.datasource-external.driver-class-name=org.hsqldb.jdbcDriver
spring.datasource-external.jpa.database-platform=org.hibernate.dialect.HSQLDialect

flyway.enabled=false
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true

DBInternalConfig

数据库内部配置


    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(basePackages = "cz.data.internal",
            entityManagerFactoryRef = "internalEntityManagerFactory",
            transactionManagerRef = "internalTransactionManager")
    public class DBConfigInternal {


        public static final String INTERNAL = "internal";

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

        @Bean(name = "internalEntityManagerFactory")
        @Primary
        public LocalContainerEntityManagerFactoryBean internalEntityManagerFactory(
                EntityManagerFactoryBuilder builder) {
            return builder
                    .dataSource(internalDataSource())
                    .packages("cz.data.internal.entity")
                    .persistenceUnit(INTERNAL)
                    .build();
        }

        @Bean(name = "internalTransactionManager")
        @Primary
        public PlatformTransactionManager internalTransactionManager() {
            JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
            jpaTransactionManager.setDataSource(internalDataSource());
            jpaTransactionManager.setPersistenceUnitName(INTERNAL);
            return jpaTransactionManager;
        }
    }

DBExternalConfig

:数据库外部配置。

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            basePackages = "cz.data.external",
            entityManagerFactoryRef = "externalEntityManagerFactory",
            transactionManagerRef = "externalTransactionManager")
    public class DBConfigExternal {


        public static final String EXTERNAL = "external";

        @Bean(name = "externalDataSource")
        @ConfigurationProperties(prefix = "spring.datasource-external")
        public DataSource externalDataSource() {
            return DataSourceBuilder.create().build();
        }

        @Bean(name = "externalEntityManagerFactory")
        public LocalContainerEntityManagerFactoryBean externalEntityManagerFactory(
                EntityManagerFactoryBuilder builder) {
            return builder
                    .dataSource(externalDataSource())
                    .packages("cz.data.external.entity")
                    .persistenceUnit(EXTERNAL)
                    .build();
        }

        @Bean(name = "externalTransactionManager")
        public PlatformTransactionManager externalTransactionManager() {
            JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
            jpaTransactionManager.setDataSource(externalDataSource());
            jpaTransactionManager.setPersistenceUnitName(EXTERNAL);
            return jpaTransactionManager;
        }
    }
M.W.

没有理由认为 spring.jpa.hibernate.ddl-auto=create 只因您有两个数据源而停止工作。Spring Boot 将自动配置 Hibernate 以使用 @Primary 的任意一个数据源。 我猜测您添加了一些额外的配置,从而关闭了 Hibernate 的自动配置,但因为您没有提供足够的信息来重新创建您正在尝试解决的问题,所以很难确定。 - Andy Wilkinson
我已经添加了一些代码片段。我对这两个选项并不是很清楚,我几乎看不到它们在哪里设置,更不用说它们具体连接到代码的哪里了。无论如何,对我来说更重要的是第二个问题,如何使其与数据源相关。 - Zveratko
请查看此链接:http://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html#howto-execute-flyway-database-migrations-on-startup - Eddú Meléndez
我知道这份文档。我想要使用自动生成,但是我没有看到可以为不同的数据源使用不同的Flyway脚本的选项。我希望能够独立初始化两个数据源。 - Zveratko
也许像这样 https://dev59.com/cmvXa4cB1Zd3GeqPJXZq#13625889,需要检查Spring Boot是否喜欢那样:-/ - Zveratko
1个回答

50

spring.jpa.hibernate.ddl-auto=create停止工作并不是因为您有两个数据源,而是因为您的应用程序创建了自己的LocalContainerEntityManagerFactoryBeans。这会导致禁用LocalContainerEntityManagerFactoryBean的自动配置,因此您现在必须自行配置它。

您可以像下面这样配置两个实体管理器具有不同的模式生成行为(第一个执行更新,第二个执行创建):

@Bean(name = "externalEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean externalEntityManagerFactory(
        EntityManagerFactoryBuilder builder) {
    Map<String, Object> properties = new HashMap<String, Object>();
    properties.put("hibernate.hbm2ddl.auto", "update");
    return builder
            .dataSource(externalDataSource())
            .packages("cz.data.external.entity")
            .persistenceUnit(EXTERNAL)
            .properties(properties)
            .build();
}

@Bean(name = "internalEntityManagerFactory")
@Primary
public LocalContainerEntityManagerFactoryBean internalEntityManagerFactory(
        EntityManagerFactoryBuilder builder) {
    Map<String, Object> properties = new HashMap<String, Object>();
    properties.put("hibernate.hbm2ddl.auto", "create");
    return builder
            .dataSource(internalDataSource())
            .packages("cz.data.internal.entity")
            .persistenceUnit(INTERNAL)
            .properties(properties)
            .build();
}

我已经按照你的建议去做了。应用程序似乎在工作,但奇怪的是我无法在hsqldb(内存中)中看到表格,这不应该是我在事务处理方面出了问题吗?所以事务仍然处于打开状态,还没有提交?:( - Zveratko
2
我也遇到了很多 org.hibernate.tool.hbm2ddl.SchemaExport : user lacks privilege or object not found: PUBLIC.NOTIFICATION 的问题。 - Zveratko
1
似乎HSQLDB进程对其他链接不可用。 - Zveratko
请问你能否添加基于XML的配置? - devanathan
@Andy - 你能在这里给我指导一下吗:https://stackoverflow.com/questions/61086749/spring-batch-unable-to-create-metadata-tables-on-postgres-and-load-actual-data? - PAA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接