2016-05-17 44 views
5

Sto utilizzando SpringBoot, insieme a Hibernate come provider di persistenza. Per la mia applicazione, ho richiesto di scegliere dinamicamente tra 2 DB.Spring AbstractRoutingDataSource + Hibernate- Hbm2ddlSchemaUpdate viene eseguito solo sul default DB

(For simplicity sake, 
    domain : localhost:8080 ---> hem1 DB 
    domain : 127.0.0.1:8080 ---> hem2 DB 
) 

In seguito è l'attuazione di AbstractRoutingDB

public class MyRoutingDataSource extends AbstractRoutingDataSource{ 
     @Override 
     protected Object determineCurrentLookupKey() { 

     /* 
     * this is derived from threadlocal set by filter for each web   
     * request 
     */ 
      return SessionUtil.getDB(); 
     } 
    } 

In seguito è la configurazione DB:

package com.hemant.basic.dataSource; 

    import java.beans.PropertyVetoException; 
    import java.util.HashMap; 
    import java.util.Map; 

    import javax.naming.ConfigurationException; 
    import javax.sql.DataSource; 

    import org.springframework.context.annotation.Bean; 
    import org.springframework.context.annotation.Configuration; 

    import com.mchange.v2.c3p0.ComboPooledDataSource; 

    @Configuration 
    public class DBConfig { 

     @Bean(name = "dataSource") 
     public DataSource dataSource() throws PropertyVetoException, 
       ConfigurationException { 
      MyRoutingDataSource routingDB = new MyRoutingDataSource(); 
      Map<Object, Object> targetDataSources = datasourceList(); 

// hem1 is the default target DB    
routingDB.setDefaultTargetDataSource(targetDataSources.get(1)); 
      routingDB.setTargetDataSources(targetDataSources); 
      routingDB.afterPropertiesSet(); 
      return routingDB; 
     } 

     private Map<Object, Object> datasourceList() throws PropertyVetoException, 
       ConfigurationException { 
      final Map<Object, Object> datasources = new HashMap<Object, Object>(); 
      ComboPooledDataSource datasource = null; 
      for (int id = 1; id <= 2; id++) { 
       datasource = getDatasource(id); 
       datasources.put(id, datasource); 
      } 
      return datasources; 
     } 

     private ComboPooledDataSource getDatasource(int id) 
       throws PropertyVetoException, ConfigurationException { 
      ComboPooledDataSource datasource = new ComboPooledDataSource(); 

      // set the connection pool properties 
      datasource.setJdbcUrl("jdbc:postgresql://localhost/hem" + id); 
      datasource.setUser("hemant"); 
      datasource.setPassword(""); 
      datasource.setDriverClass("org.postgresql.Driver"); 
      datasource.setMaxPoolSize(30); 
      datasource.setInitialPoolSize(10); 
      datasource.setMinPoolSize(10); 

      return datasource; 
     } 
    } 

Inoltre seguente impostazione è in application.properties in modo che l'aggiornamento dello schema automatico è attivo.

# Hibernate ddl auto (create, create-drop, update) 
spring.jpa.hibernate.ddl-auto = update 

Problema: quando inizio l'applicazione, l'aggiornamento dello schema hbm2ddl viene eseguita solo sul HEM1 (defaultTargetDb), ma non su altri database di destinazione

seguito è la parte di tronchi di avvio

[main] org.hibernate.tool.hbm2ddl.SchemaUpdate : HHH000228: Running hbm2ddl schema update 
[main] org.hibernate.tool.hbm2ddl.SchemaUpdate : HHH000102: Fetching database metadata 
[main] org.hibernate.tool.hbm2ddl.SchemaUpdate : HHH000396: Updating schema 
[main] java.sql.DatabaseMetaData    : HHH000262: Table not found: users 
[main] java.sql.DatabaseMetaData    : HHH000262: Table not found: users 
[main] java.sql.DatabaseMetaData    : HHH000262: Table not found: users 
[main] org.hibernate.tool.hbm2ddl.SchemaUpdate : HHH000232: Schema update complete`enter code here` 

QUESTO È ESEGUITO SOLO PER 1 DB.

** Più tardi, quando eseguo resto URL dire

GET localhost: 8080/Utenti - Risultati vengono recuperate con successo per il DB HEM1 che viene aggiornato.

Ma quando 127.0.0.1:8080/users GET si accede, dal momento che lo schema non è aggiornato/creato, il risultato e 'Eccezione SQL **

Come possiamo garantire che "aggiornamento dello schema hbm2ddl" viene eseguita su tutti i database di destinazione di AbstractRoutingDataSource

risposta

0

Per quanto ne so, non è possibile impostare l'esportazione dello schema in un ambiente multi-tenant. Quando si definisce un ambiente multi-tenant, per impostazione predefinita si collegherà a un database predefinito solo per ottenere una connessione. Questo è il motivo per cui viene creato solo in un database. Non accederà a tutti i database/schemi per creare perché non si conoscono l'un l'altro.

Salvare un database SQL creare un file ed eseguirlo ogni volta che si crea un nuovo titolare. Penso che tu possa usare Spring PersistenceContext per crearlo per te quando richiesto.