Reputation: 133
I met a problem when using multi datasources. I extends AbstractRoutingDataSource
and create it as bean.like this:
@Configuration
public class JpaConfiguration{
@Bean
public void DataSource dataSource(){
return new AbstractRoutingDataSource(){...}
}
in my yml file,I set spring.jpa.hibernate.ddl-auto update.
spring:
...
jpa:
hibernate:
ddl-auto: update
...
everything gone right. but when I change dataSource, like another schema.I must create tables myself.when I change dataSource or add dataSource into my routingDataSource
runtime, is there any way to let hibernate auto create tables?
-----update----
spring boot auto create LocalContainerEntityManagerFactoryBean
,and when application start,it use defaultDataSource, here is code in 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;
}
With default dataSource ,hibernate auto create tables.but when I use another dataSource, it doesn't works.
Upvotes: 1
Views: 2174
Reputation: 31
The trick for me was setting the em properties like this:
properties.put("hibernate.hbm2ddl.auto", "create-drop");
properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
In my case, I was using H2, so you can replace the Dialect with whatever db you are using.
You can find the whole context of the configuration file below:
@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;
}
}
Upvotes: 3
Reputation: 18235
To use custom datasource, you must tell your EntityManager to load JPA properties:
@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();
}
Upvotes: 0