2017-04-18 103 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來初始化新數據。「 –

相關問題