如何在SpringBoot 2中创建数据源?

时间:2019-06-18 21:16:09

标签: hibernate spring-boot

我尝试访问一个声明为:

的DataSource bean。
import numpy as np
from scipy.optimize import fsolve

def system(z):
   #arbitrary system of 3 nonlinear equations
   x1 = z[0]
   x2 = z[1]
   x3 = z[2]

   F = np.empty((3))
   F[0] = 20* x1 + x2**2
   F[1] = x2 - x1
   F[2] = x3 + 5 - x1*x2

   return F

def system2(z):
   #arbitrary system of 6 nonlinear equations
   x1 = z[0]
   x2 = z[1]
   x3 = z[2]
   x4 = z[3]
   x5 = z[4]
   x6 = z[5]

   F = np.empty((6))
   F[0] = 20* x1 + x2**2
   F[1] = x2 - x1
   F[2] = x3 + 5 - x1*x2
   F[3] = x3 + x2
   F[4] = x5 + x4**2
   F[5] = x6**2 + x1 - 20

   return F

uInitial = np.array([1,1,1])
u = fsolve(system,uInitial)
print('Solution: ',u)
print('Solution check: ',system(u),'\n') #yields zeros as expected

vInitial = np.array([1,1,1,1,1,1])
v = fsolve(system2,vInitial)
print('Solution: ',v)
print('Solution check: ',system2(v)) #unexpectedly does not yield zeros. Equations not solved correctly.

这在Spring Boot 1.5中有效,但是如果在Spring Boot 2.5中失败并出现错误:

@Bean
@Primary
@ConfigurationProperties(prefix = "app.customer.datasource.properties")
public DataSource customerDataSource() {
    return customerDataSourceProperties().initializeDataSourceBuilder()
            .type(DataSource.class).build();
}

我也尝试对参数进行硬编码(请参见下文),但是错误更改为NullPointerException。

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Specified class is an interface
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:119)
at org.springframework.boot.jdbc.DataSourceBuilder.build(DataSourceBuilder.java:75)
at demo.customer.CustomerConfig.customerDataSource(CustomerConfig.java:55)
at demo.customer.CustomerConfig$$EnhancerBySpringCGLIB$$1637ca06.CGLIB$customerDataSource$4(<generated>)
at demo.customer.CustomerConfig$$EnhancerBySpringCGLIB$$1637ca06$$FastClassBySpringCGLIB$$50f070a1.invoke(<generated>)

我得到的NPE例外是:

@Bean
@Primary
public DataSource customerDataSource() {
    DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
    dataSourceBuilder.driverClassName("org.h2.Driver");
    dataSourceBuilder.url("jdbc:h2:mem:customers");
    dataSourceBuilder.username("SA");
    dataSourceBuilder.password("");
    return dataSourceBuilder.build();
}

如果我选择“ .type(HikariDataSource.class)”,我也会看到相同的NPE。

您知道自1.5版以来发生了什么变化吗?

2 个答案:

答案 0 :(得分:1)

基于Ananthapadmanabhan的答案,这是我最终使用的代码:

@Bean
public DataSource orderDataSource() {
    DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
    dataSourceBuilder.driverClassName("org.h2.Driver");
    dataSourceBuilder.url("jdbc:h2:mem:orders");
    dataSourceBuilder.username("SA");
    dataSourceBuilder.password("");
    return dataSourceBuilder.build();
}

@Bean(name = "orderEntityManager")
public LocalContainerEntityManagerFactoryBean orderEntityManagerFactory() {
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setDatabasePlatform("org.hibernate.dialect.H2Dialect");
    vendorAdapter.setGenerateDdl(true);

    LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
    factoryBean.setJpaVendorAdapter(vendorAdapter);
    factoryBean.setDataSource(this.orderDataSource());
    factoryBean.setPackagesToScan("demo.order");
    factoryBean.setPersistenceUnitName("order");

    return factoryBean;
}

@Bean
public JpaTransactionManager orderTransactionManager(EntityManagerFactory orderEntityManager) {
    return new JpaTransactionManager(orderEntityManager);
}

答案 1 :(得分:0)

您可以提供一个配置类并注册如下所示的Bean:

@Configuration
public class DataSourceConfig {

    @Bean
    public DataSource getDataSource() {
        DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
        dataSourceBuilder.driverClassName("org.h2.Driver");
        dataSourceBuilder.url("jdbc:h2:mem:test");
        dataSourceBuilder.username("SA");
        dataSourceBuilder.password("");
        return dataSourceBuilder.build();
    }
}

如果您具有application.yml作为依赖项,那么您还可以在springboot中提供application.propertiesspring-boot-starter-data-jpa中的值,并且springboot将自动为您创建数据源bean。 application.properties

spring.datasource.url=jdbc:h2:your:url
spring.datasource.driver-class-name=org.h2.Driver

对于您的情况,错误:

Caused by: java.lang.NullPointerException   
at org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter.determineDatabaseDialectClass(HibernateJpaVendorAdapter.java:185)  

之所以出现,是因为方法determineDatabaseDialectClass()返回了Hibernate数据库的方言类;如果找不到则返回null。

官方doc

因此,尝试在application.properties中添加以下内容以设置方言或以编程方式添加方言:

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect

或以编程方式使用像这样的bean:

@Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(){
        LocalContainerEntityManagerFactoryBean factoryBean
            = new LocalContainerEntityManagerFactoryBean();

        factoryBean.setDataSource( this.restDataSource() );
        factoryBean.setPackagesToScan( new String[ ] { "com.jverstry" } );
        factoryBean.setPersistenceUnitName("MyMy");

        Properties props = new Properties();
        props.put("hibernate.dialect",  "org.hibernate.dialect.MySQLDialect");
        props.put("hibernate.hbm2ddl.auto", "create");
        factoryBean.setJpaProperties(props);
        return factoryBean;
    }

通常,默认情况下springoot会处理此问题并为此提供默认实现(如果您已在属性文件等中提供了所有值)。您也可以通过xml进行配置,但是由于它是通过java的springboot配置,因此非常值得赞赏。