Как создать источник данных в SpringBoot 2? - PullRequest
0 голосов
/ 19 июня 2019

Я пытаюсь получить доступ к компоненту DataSource, объявленному как:

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

Это работает в Spring Boot 1.5, но в случае сбоя в Spring Boot 2.5 с ошибкой:

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>)

Iтакже попытался жестко закодировать параметры (см. ниже), но ошибка изменилась на NullPointerException.

@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();
}

Исключение NPE, которое я получаю:

Caused by: java.lang.NullPointerException   
at org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter.determineDatabaseDialectClass(HibernateJpaVendorAdapter.java:185)   
at org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter.buildJpaPropertyMap(HibernateJpaVendorAdapter.java:143)     
at org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter.getJpaPropertyMap(HibernateJpaVendorAdapter.java:127)   
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:346)   
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
....

Я также вижу тот же NPE, если выбираю ".type (HikariDataSource.class)".

Ты хоть представляешь, что изменилось с версии 1.5?

Ответы [ 2 ]

1 голос
/ 19 июня 2019

Основываясь на ответе Анантхападманабхана, вот код, который я наконец-то использовал:

@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);
}
0 голосов
/ 19 июня 2019

Вы можете предоставить класс конфигурации и зарегистрировать компонент, как показано ниже:

@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 или application.properties в Springboot, если у вас есть spring-boot-starter-data-jpa в качестве зависимости, и Springboot автоматически создаст компонент источника данных для вас. 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, или ноль, если ничего не найдено.

Официальный Документ

Итак, попробуйте добавить следующее в application.properties, чтобы установить диалект или добавить его программно:

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

или использование программно с использованием бобов, например:

@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, но так как это настройки Springboot через java, очень приветствуются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...