2017-04-18 144 views
4

schema.sql中的脚本获取执行,但data.sql中的脚本未执行, 不确定我丢失了什么?Spring Boot和数据库初始化工作不正常

我使用Spring启动有两个数据源,我的数据的基础配置如下

@PropertySource({ "classpath:application.properties" }) 
@Configuration 
@EnableJpaRepositories(
    basePackages = "com.projectx.mysql", 
    entityManagerFactoryRef = "userEntityManager", 
    transactionManagerRef = "userTransactionManager" 
) 
public class DataBaseConfig { 

    @Autowired 
    Environment env; 


    @Bean 
    @Primary 
    public LocalContainerEntityManagerFactoryBean userEntityManager() { 
     LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); 
     em.setDataSource(primaryDataSource()); 
     em.setPackagesToScan(new String[] { "com.projectx.mysql" }); 
     HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
     em.setJpaVendorAdapter(vendorAdapter); 
     HashMap<String, Object> properties = new HashMap<String, Object>(); 
     properties.put("hibernate.hbm2ddl.auto", env.getProperty("spring.jpa.hibernate.ddl-auto_mysql")); 
     properties.put("hibernate.dialect", env.getProperty("spring.jpa.properties.hibernate.dialect_mysql")); 
     properties.put("hibernate.show_sql", env.getProperty("spring.jpa.show-sql")); 
     em.setJpaPropertyMap(properties); 

     return em; 
    } 

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


    @Primary 
    @Bean 
    public PlatformTransactionManager userTransactionManager() { 
     JpaTransactionManager transactionManager = new JpaTransactionManager(); 
     transactionManager.setEntityManagerFactory(userEntityManager().getObject()); 
     return transactionManager; 
    } 
} 

和属性文件配置如下

spring.datasource.initialize=true 
spring.datasource.url=jdbc:mysql://localhost/test 
spring.datasource.username=root 
spring.datasource.password= 
spring.datasource.driverClassName=com.mysql.jdbc.Driver 
spring.jpa.show-sql: true 
spring.jpa.hibernate.ddl-auto_mysql=update 
spring.jpa.properties.hibernate.dialect_mysql=org.hibernate.dialect.MySQL5Dialect 
+0

你也可以张贴在那里你执行的SQL脚本的代码?你如何处理第二个数据源? – Simon

+0

其他数据连接是mongodb server.The问题是,如果我指定它为schema.sql然后内容得到执行,但如果我把相同的内容data.sql它不会执行 – MasterCode

+0

什么是data.sql和schema.sql? – Simon

回答

0

的问题是与数据源的初始化 当我们看到的内容org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer类通过* .SQL files.It负责数据库的初始化后具有构造方法如下

@PostConstruct 
    public void init() { 
     if (!this.properties.isInitialize()) { 
      logger.debug("Initialization disabled (not running DDL scripts)"); 
      return; 
     } 
     if (this.applicationContext.getBeanNamesForType(DataSource.class, false, 
       false).length > 0) { 
      this.dataSource = this.applicationContext.getBean(DataSource.class); 
     } 
     if (this.dataSource == null) { 
      logger.debug("No DataSource found so not initializing"); 
      return; 
     } 
     runSchemaScripts(); 
    } 

的runSchemaScripts()方法将初始化休眠模式的创建和更新操作之前的数据perfomed因此,如果数据库架构不产生。然后,如果你提供的SQL脚本,但我希望在创建后的架构/更新来执行操作,该类包含

@Override 
    public void onApplicationEvent(DataSourceInitializedEvent event) { 
     if (!this.properties.isInitialize()) { 
      logger.debug("Initialization disabled (not running data scripts)"); 
      return; 
     } 
     // NOTE the event can happen more than once and 
     // the event datasource is not used here 
     if (!this.initialized) { 
      runDataScripts(); 
      this.initialized = true; 
     } 
    } 

这就是所谓的这些方法将创建模式,如果休眠模式创建后/更新操作时,我们有弹簧靴默认Datasource创建机制。 但是由于我自己创建了Datasource,所以它并没有创建DataSourceInitializedEvent,所以数据启动脚本data.sql未被执行。 因此,我已经更改了我的数据源创建逻辑以创建DataSourceInitializedEvent,如下所示,并解决了我的问题。

@Autowired 
    private ConfigurableApplicationContext applicationContext; 

    @Bean 
    @Primary 
    public LocalContainerEntityManagerFactoryBean userEntityManager() { 
     LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); 
     em.setDataSource(primaryDataSource()); 
     em.setPackagesToScan(new String[] { "com.projectx.mysql" }); 
     HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
     em.setJpaVendorAdapter(vendorAdapter); 
     HashMap<String, Object> properties = new HashMap<String, Object>(); 
     properties.put("hibernate.hbm2ddl.auto", env.getProperty("spring.jpa.hibernate.ddl-auto_mysql")); 
     properties.put("hibernate.dialect", env.getProperty("spring.jpa.properties.hibernate.dialect_mysql")); 
     properties.put("hibernate.show_sql", env.getProperty("spring.jpa.show-sql")); 
     em.setJpaPropertyMap(properties); 

     this.applicationContext.publishEvent(new DataSourceInitializedEvent(primaryDataSource())); 

     return em; 
    } 

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

新增this.applicationContext.publishEvent(new DataSourceInitializedEvent(primaryDataSource()));创建DataSourceInitializedEvent事件

0

我设法得到实例2数据源并使用this test project启动其中一个模式和数据。希望帮助,也许我错过了你的一些要求,这使得我的建议无效:(

对于裁判(猜你已经看到了这一点):https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-two-datasources

+0

问题不在于两个连接工作正常。但数据初始化没有完成。但模式脚本运行正常 – MasterCode

+0

您是否尝试过设置ddl-auto = none。 “如果您想在JPA应用程序(使用Hibernate)中使用schema.sql初始化,那么如果Hibernate尝试创建相同的表,则ddl-auto = create-drop会导致错误。为避免这些错误,将ddl-auto显式设置为“”(首选)或“none”。无论您是否使用ddl-auto = create-drop,都可以使用data.sql来初始化新数据。“ –

相关问题