Spring Boot Hibernate自动创建具有多个数据源的表

时间:2018-08-15 02:54:23

标签: hibernate spring-boot spring-data-jpa

使用多个数据源时遇到问题。我扩展了AbstractRoutingDataSource并将其创建为bean。像这样:

@Configuration
public class JpaConfiguration{
    @Bean
    public void DataSource dataSource(){
        return new AbstractRoutingDataSource(){...}
    }

在我的yml文件中,我设置了spring.jpa.hibernate.ddl-自动更新。

spring:
    ...
    jpa:
        hibernate:
            ddl-auto: update
    ...

一切正常。但是当我更改数据源时,就像另一个模式一样。我必须自己创建表。当我更改数据源或将数据源添加到routingDataSource运行时时,是否有任何方法可以让休眠自动创建表?

-----更新---- 春季启动自动创建LocalContainerEntityManagerFactoryBean,并在应用程序启动时使用defaultDataSource,这是AbstractRoutingDataSource中的代码:

protected DataSource determineTargetDataSource() {
    Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
    Object lookupKey = determineCurrentLookupKey();
    DataSource dataSource = this.resolvedDataSources.get(lookupKey);
    if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
        dataSource = this.resolvedDefaultDataSource;
    }
    if (dataSource == null) {
        throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
    }
    return dataSource;
}

使用默认的dataSource时,休眠会自动创建表。但是当我使用另一个dataSource时,它将无法正常工作。

2 个答案:

答案 0 :(得分:0)

要使用自定义数据源,必须告诉EntityManager加载JPA属性:

@Bean
public LocalContainerEntityManagerFactoryBean getEntityManagerFactory(EntityManagerFactoryBuilder builder, 
                    DataSource dataSource, 
                    JpaProperties jpaProperties) {
    return builder
            .dataSource(dataSource)
            .packages(YourEntity.class)
            .persistenceUnit("yourEmName")
            // Important. load properties
            .properties(jpaProperties.getHibernateProperties(dataSource))
            .build();
}

答案 1 :(得分:0)

我的诀窍是像这样设置 em 属性:

properties.put("hibernate.hbm2ddl.auto", "create-drop");
properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");

就我而言,我使用的是 H2,因此您可以用您正在使用的任何数据库替换方言。

您可以在下面找到配置文件的整个上下文:

@Configuration
@PropertySource({"classpath:application.properties"})
@EnableJpaRepositories(
        basePackages = "com.spring.boot.repository.h2",
        entityManagerFactoryRef = "h2EntityManager",
        transactionManagerRef = "h2TransactionManager"
)
public class H2PersistenceConfiguration {

    @Autowired
    private Environment env;

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

    @Primary
    @Bean
    public LocalContainerEntityManagerFactoryBean h2EntityManager() {
        final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(h2DataSource());
        em.setPackagesToScan("com.spring.boot.model.h2");

        final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        final HashMap<String, Object> properties = new HashMap<String, Object>();
        properties.put("hibernate.hbm2ddl.auto", "create-drop");
        properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
        em.setJpaPropertyMap(properties);

        return em;
    }

    @Primary
    @Bean
    public PlatformTransactionManager h2TransactionManager() {
        final JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(h2EntityManager().getObject());
        return transactionManager;
    }
}