I am implementing a backend with two database connections. One to a MS Access DB and another one to a MySQL DB. I've setup two configuration classes and the application is running without any error message, but does not create the tables for my entities in mysql db.
Project structure:
my.backend
|
--> configuration
--> controller
--> exceptions
--> model
| |
| --> mysql
| --> msaccess
|
--> repo
| |
| --> mysql
| --> msaccess
|
--> service
My configuration files are looking like this:
MySQL Configuration:
imports [...]
#Configuration
#EnableJpaRepositories(
entityManagerFactoryRef = "mysqlEntityManagerFactory",
transactionManagerRef = "mysqlTransactionManager",
basePackages = "my.backend.repo.mysql"
)
public class MySqlJpaConfig {
#Autowired
private Environment env;
#Bean
#Primary
#ConfigurationProperties(prefix = "mysql")
public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(mysqlDataSource());
em.setPackagesToScan("my.backend.model.mysql");
em.setPersistenceUnitName("mysql");
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
HashMap<String, Object> jpaProperties = new HashMap<>();
jpaProperties.put("hibernate.ddl-auto",
env.getProperty("mysql.jpa.hibernate.ddl-auto"));
jpaProperties.put("hibernate.dialect",
env.getProperty("mysql.jpa.properties.hibernate.dialect"));
em.setJpaPropertyMap(jpaProperties);
return em;
}
#Primary
#Bean
public DataSource mysqlDataSource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
dataSource.setUrl(env.getProperty("mysql.url"));
dataSource.setUsername(env.getProperty("mysql.username"));
dataSource.setPassword(env.getProperty("mysql.password"));
dataSource.setDriverClassName(Objects.requireNonNull(env.getProperty("mysql.driver-class-name")));
return dataSource;
}
#Primary
#Bean
public PlatformTransactionManager mysqlTransactionManager() {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
mysqlEntityManagerFactory().getObject());
return transactionManager;
}
}
MS Access Configuration:
#Configuration
#EnableJpaRepositories(
entityManagerFactoryRef = "msaccessEntityManagerFactory",
transactionManagerRef = "msaccessTransactionManager",
basePackages = "my.backend.repo.msaccess"
)
#EnableTransactionManagement
public class MsAccessJpaConfig {
#Autowired
private Environment env;
#Bean
#ConfigurationProperties(prefix = "mysql")
public LocalContainerEntityManagerFactoryBean msaccessEntityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(msaccessDataSource());
em.setPackagesToScan("my.backend.model.msaccess");
em.setPersistenceUnitName("msaccess");
//em.setPersistenceProvider(new HibernatePersistenceProvider());
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
HashMap<String, Object> jpaProperties = new HashMap<>();
jpaProperties.put("hibernate.dialect",
env.getProperty("msaccess.jpa.properties.hibernate.dialect"));
em.setJpaPropertyMap(jpaProperties);
return em;
}
#Bean
public DataSource msaccessDataSource() {
DriverManagerDataSource dataSource
= new DriverManagerDataSource();
dataSource.setUrl(env.getProperty("msaccess.url"));
dataSource.setDriverClassName(Objects.requireNonNull(env.getProperty("msaccess.driver-class-name")));
return dataSource;
}
#Bean
public PlatformTransactionManager msaccessTransactionManager() {
JpaTransactionManager transactionManager
= new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
msaccessEntityManagerFactory().getObject());
return transactionManager;
}
}
And my application.properties file:
spring.jpa.show-sql=true
spring.jpa.open-in-view=false
# MySQL config
mysql.url=jdbc:mysql://localhost:3306/my_database
mysql.username=
mysql.password=
mysql.driver-class-name=com.mysql.cj.jdbc.Driver
mysql.jpa.hibernate.ddl-auto=update
mysql.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
# MS Access config
msaccess.url=jdbc:ucanaccess://c:/users/username/documents/test.accdb
msaccess.driver-class-name=net.ucanaccess.jdbc.UcanaccessDriver
msaccess.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServerDialect
When I run my application without the custom configuration and only one vanilla database connection (only MySQL) everything works fine. Also if I run this and perform a get request I get a Error that the table does not exist (obviously), so the connection to MySQL is there but the application just does not create the tables I need. Btw MS Access is working the same way, but I do not want a table generation there.
Am I missing some configuration for the connection?
Thanks for your help!
Cheers, niklas
My guess is that you have to use hibernate.hbm2ddl.auto instead of hibernate.ddl-auto in your jpa properties configuration, since that is the name hibernate looks for
Related
I am using spring boot and spring batch. For meta table i want to use mysql and for all business thing i want to use db2 as a database.When i implemented getting error.
application.properties
spring.datasource.url = jdbc:mysql://localhost:3306/local
spring.datasource.username = root
spring.datasource.password = root
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.seconddatasource.url=jdbc:db2://***************
spring.seconddatasource.username=******
spring.seconddatasource.password=****
spring.seconddatasource.driverClassName=com.ibm.db2.jcc.DB2Driver
BatchCongig.java
#Configuration
#EnableBatchProcessing
public class BatchConfiguration {
#Autowired
public JobBuilderFactory jobBuilderFactory;
#Autowired
public StepBuilderFactory stepBuilderFactory;
#Autowired
public DataSource dataSourceSecond;
#Bean
#ConfigurationProperties(prefix="spring.seconddatasource")
public javax.sql.DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
#Bean
#Primary
#ConfigurationProperties(prefix="spring.datasource")
public javax.sql.DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
#Bean
public JdbcCursorItemReader<User> reader()
{
JdbcCursorItemReader<User> reader=new JdbcCursorItemReader<>();
reader.setDataSource(dataSourceSecond);
reader.setSql("Select ACCT_ID from ACCT_table FETCH FIRST 100 ROWS ONLY");
reader.setRowMapper(new UserRowerMapper());
return reader;
}
#Bean
public UserItemProcessor processor()
{
return new UserItemProcessor();
}
#Bean
public Step step1()
{
return stepBuilderFactory.get("step1").<User,User>chunk(10)
.reader(reader())
.processor(processor())
.build();
}
#Bean
public Job job1()
{
return jobBuilderFactory.get("jobakjkkj")
.incrementer(new RunIdIncrementer())
.flow(step1())
.end()
.build();
}
}
error stack
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:779) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:747) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at com.schwab.cat.SpringBatchDbReadApplication.main(SpringBatchDbReadApplication.java:10) [classes/:na]
Caused by: java.lang.IllegalStateException: To use the default BatchConfigurer the context must contain no more thanone DataSource, found 2
at org.springframework.batch.core.configuration.annotation.AbstractBatchConfiguration.getConfigurer(AbstractBatchConfiguration.java:108) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration.initialize(SimpleBatchConfiguration.java:114) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$ReferenceTargetSource.createObject(SimpleBatchConfiguration.java:142) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.aop.target.AbstractLazyCreationTargetSource.getTarget(AbstractLazyCreationTargetSource.java:86) ~[spring-aop-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:192) ~[spring-aop-4.3.8.RELEASE.jar:4.3.8.RELEASE]
at com.sun.proxy.$Proxy46.getJobInstances(Unknown Source) ~[na:na]
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.getNextJobParameters(JobLauncherCommandLineRunner.java:131) ~[spring-boot-autoconfigure-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.execute(JobLauncherCommandLineRunner.java:212) ~[spring-boot-autoconfigure-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.executeLocalJobs(JobLauncherCommandLineRunner.java:231) ~[spring-boot-autoconfigure-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.launchJobFromProperties(JobLauncherCommandLineRunner.java:123) ~[spring-boot-autoconfigure-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.run(JobLauncherCommandLineRunner.java:117) ~[spring-boot-autoconfigure-1.5.3.RELEASE.jar:1.5.3.RELEASE]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:776) [spring-boot-1.5.3.RELEASE.jar:1.5.3.RELEASE]
... 6 common frames omitted
I found one jira https://jira.spring.io/browse/BATCH-2537 which say that "#Primary datasource with #EnableBatchProcessing does not work for using multiple datasources" if this is correct please tell me how i can achive same.
I also found this How to use 2 or more databases with spring? but not helpful in my case.
As M. Deinum suggested, I would also put the configuration of the datasources in a separate file.
Beside that, there are the following problems in your configuration file:
SpringBatch looks for a datasource named "dataSource" (note the capital S). If it doesn't find one, it looks for any datasource it finds. However, if it finds more than one, it throws an exception -> the one you observed.
In your configuration file, you create two datasources and inject one (#Autowired Datasource dataSourceSecond). This would cause the next problem, since you don't have a datasource with this name. (You only defined the datasources "secondaryDataSource" and "primaryDataSource"). This would also lead to an exception.
Here is how I would organise my configurations
#Configuration
public DatasourceConfiguration {
#Bean
#ConfigurationProperties(prefix="spring.seconddatasource")
public javax.sql.DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
// note the new name: dataSource -> this is the name springBatch is looking for
#Bean
#ConfigurationProperties(prefix="spring.datasource")
public javax.sql.DataSource dataSource() {
return DataSourceBuilder.create().build();
}
}
#Configuration
#EnableBatchProcessing
#Import(DatasourceConfiguration.class)
public class BatchConfiguration {
#Autowired
public JobBuilderFactory jobBuilderFactory;
#Autowired
public StepBuilderFactory stepBuilderFactory;
// note the name
#Autowired
public DataSource secondaryDataSource;
#Bean
public JdbcCursorItemReader<User> reader()
{
JdbcCursorItemReader<User> reader=new JdbcCursorItemReader<>();
// note the name
reader.setDataSource(secondaryDataSource);
reader.setSql("Select ACCT_ID from ACCT_table FETCH FIRST 100 ROWS ONLY");
reader.setRowMapper(new UserRowerMapper());
return reader;
}
...
I've also written an more thouroughly answer to a similar question:
I would like to create a spring batch project where batch does not use my datasource
I prepared website in Spring/Maven with use of MySQL db, Tomcat. I decided to use Heroku free account, because I have domain, db and Java in one place. Problem is that Heroku uses postgresql for free but mysql is payable. I would like to ask you help and explanation clearly what I should change in my application's code(pom.xml, hibernate.properties etc) to use postgresql instead of mysql. Below I show files I think should be changed. Do I have to add any new files? I beg your indulgence.
***POM.XML***
jdbc.driver.class.name =com.mysql.jdbc.Driver
jdbc.url =jdbc:mysql://localhost:3306/web_users?useSSL=false&characterEncoding=UTF-8
jdbc.user.name =root
jdbc.password =root
hibernate.hbm2ddl.auto =update
hibernate.show_sql =true
hibernate.format_sql =true
hibernate.generate_statistics=false
***HibernateConfig.java***
#Configuration
#PropertySource(value = {"classpath:hibernate.properties"})
#EnableJpaRepositories(basePackages = "com.website.dao")
public class HibernateConfig {
#Autowired
private Environment environment;
// 1. create DataSource
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driver.class.name"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.user.name"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
return dataSource;
}
// 2. EntityManagerFactory
#Bean
public EntityManagerFactory entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
Properties properties = new Properties();
properties.put("hibernate.hbm2ddl.auto", environment.getProperty("hibernate.hbm2ddl.auto"));
properties.put("hibernate.show_sql", environment.getProperty("hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getProperty("hibernate.format_sql"));
properties.put("hibernate.generate_statistics", environment.getProperty("hibernate.generate_statistics"));
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setPackagesToScan("com.website.model");
factoryBean.setJpaVendorAdapter(vendorAdapter);
factoryBean.setJpaProperties(properties);
factoryBean.setDataSource(dataSource());
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
I am trying to implement multiple database with Spring Boot Hikari CP. I am getting
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: hikari_primary,hikari_secondary
For your reference I am attaching my spring boot datasource configuration files,
please dont go over primary and secondary naming conventions(they dont represent priorities), my requirement it to have two connection pool for two different databases.
Any help is appreciated
1.application.properties
spring.datasource.dataSourceClassName=com.microsoft.sqlserver.jdbc.SQLServerDataSource
primary.spring.datasource.url=jdbc:sqlserver://xxx.xxx.xxx.xxx:1433;DatabaseName=training
primary.spring.datasource.username=training
primary.spring.datasource.password=training
primary.spring.datasource.poolName=hikari_primary
primary.spring.datasource.maximumPoolSize=5
primary.spring.datasource.minimumIdle=3
primary.spring.datasource.maxLifetime=2000000
primary.spring.datasource.connectionTimeout=30000
primary.spring.datasource.idleTimeout=30000
primary.spring.datasource.pool-prepared-statements=true
primary.spring.datasource.max-open-prepared-statements=250
secondary.spring.datasource.url=jdbc:sqlserver://xxx.xxx.xxx.xxx:1433;DatabaseName=dev_xxxxx_core_v3
secondary.spring.datasource.username=developer
secondary.spring.datasource.password=Developer
secondary.spring.datasource.poolName=hikari_secondary
secondary.spring.datasource.maximumPoolSize=50
secondary.spring.datasource.minimumIdle=30
secondary.spring.datasource.maxLifetime=2000000
secondary.spring.datasource.connectionTimeout=30000
secondary.spring.datasource.idleTimeout=30000
secondary.spring.datasource.pool-prepared-statements=true
secondary.spring.datasource.max-open-prepared-statements=300
2. PrimaryDataSourceConfig.java
#Configuration
public class PrimaryDataSourceConfig {
#Value("${primary.spring.datasource.username}")
private String user;
#Value("${primary.spring.datasource.password}")
private String password;
#Value("${primary.spring.datasource.url}")
private String dataSourceUrl;
#Value("${spring.datasource.dataSourceClassName}")
private String dataSourceClassName;
#Value("${primary.spring.datasource.poolName}")
private String poolName;
#Value("${primary.spring.datasource.connectionTimeout}")
private int connectionTimeout;
#Value("${primary.spring.datasource.maxLifetime}")
private int maxLifetime;
#Value("${primary.spring.datasource.maximumPoolSize}")
private int maximumPoolSize;
#Value("${primary.spring.datasource.minimumIdle}")
private int minimumIdle;
#Value("${primary.spring.datasource.idleTimeout}")
private int idleTimeout;
#Bean(name="hikari_primary")
public HikariDataSource getHikariDataSourcePrimary() {
Properties dsProps = new Properties();
dsProps.put("url", dataSourceUrl);
dsProps.put("user", user);
dsProps.put("password", password);
Properties configProps = new Properties();
configProps.put("dataSourceClassName", dataSourceClassName);
configProps.put("poolName", poolName);
configProps.put("maximumPoolSize", maximumPoolSize);
configProps.put("minimumIdle", minimumIdle);
configProps.put("minimumIdle", minimumIdle);
configProps.put("connectionTimeout", connectionTimeout);
configProps.put("idleTimeout", idleTimeout);
configProps.put("dataSourceProperties", dsProps);
HikariConfig hc = new HikariConfig(configProps);
HikariDataSource ds = new HikariDataSource(hc);
return ds;
}
}
3. SecondayDataSourceConfig.java
#Configuration
public class SecondaryDataSourceConfig {
#Value("${secondary.spring.datasource.username}")
private String user;
#Value("${secondary.spring.datasource.password}")
private String password;
#Value("${secondary.spring.datasource.url}")
private String dataSourceUrl;
#Value("${spring.datasource.dataSourceClassName}")
private String dataSourceClassName;
#Value("${secondary.spring.datasource.poolName}")
private String poolName;
#Value("${secondary.spring.datasource.connectionTimeout}")
private int connectionTimeout;
#Value("${secondary.spring.datasource.maxLifetime}")
private int maxLifetime;
#Value("${secondary.spring.datasource.maximumPoolSize}")
private int maximumPoolSize;
#Value("${secondary.spring.datasource.minimumIdle}")
private int minimumIdle;
#Value("${secondary.spring.datasource.idleTimeout}")
private int idleTimeout;
#Bean(name="hikari_secondary")
public HikariDataSource getHikariDataSourceSecondary() {
Properties dsProps = new Properties();
dsProps.put("url", dataSourceUrl);
dsProps.put("user", user);
dsProps.put("password", password);
Properties configProps = new Properties();
configProps.put("dataSourceClassName", dataSourceClassName);
configProps.put("poolName", poolName);
configProps.put("maximumPoolSize", maximumPoolSize);
configProps.put("minimumIdle", minimumIdle);
configProps.put("minimumIdle", minimumIdle);
configProps.put("connectionTimeout", connectionTimeout);
configProps.put("idleTimeout", idleTimeout);
configProps.put("dataSourceProperties", dsProps);
HikariConfig hc = new HikariConfig(configProps);
HikariDataSource ds = new HikariDataSource(hc);
return ds;
}
}
4. Application.java
#SpringBootApplication
#ComponentScan("com.xxxx.springsql2o")
#EnableAutoConfiguration
public class Application
{
public static void main( String[] args )
{
SpringApplication.run(Application.class, args);
}
#Autowired
#Qualifier("hikari_primary")
DataSource hikariDataSourcePrimary;
#Autowired
#Qualifier("hikari_secondary")
DataSource hikariDataSourceSecondary;
#Bean(name= "primary_db")
public Sql2o getPrimarySql2o()
{
return new Sql2o(hikariDataSourcePrimary);
}
#Bean(name= "secondary_db")
public Sql2o getSecondarySql2o()
{
return new Sql2o(hikariDataSourceSecondary);
}
}
Spring boot is auto-configuring your application via #EnableAutoConfiguration (note that this annotation is already included in the composed #SpringBootApplication annotation). So my guess would be that you have some dependency that spring is trying to auto-configure (e.g. JPA) which uses/needs DataSource. If you can live with this, you can add #Primary to on of your DataSource Bean provider methods in order to satisfy that dependency.
So, for instance:
#Bean(name="hikari_primary")
#Primary
public HikariDataSource getHikariDataSourcePrimary() {...
Even if this should work, it would be recommended to remove auto-configuration for e.g. JPA or whatever spring boot is trying to auto-configure but you don't use/need and configure everything manually as it suits your application needs. Have two databases is certainly a custom configuration and does not conform to the spring boot easy-out-of-the-box approach.
I need to create a database named test in my local mysql server which i will use to setup my datasource bean. I am using the following spring configuration for setting up the datasource and jdbctemplate for my testing
#Configuration
class Config {
#Bean(initMethod = "setupDatabase")
public DataSource getDataSource() {
String url = "jdbc:mysql://localhost:3306/test";
DriverManagerDataSource dataSource = new DriverManagerDataSource(
url, settings.getUsername(), settings.getPassword());
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
return dataSource;
}
#Bean
public JdbcTemplate getJdbcTemplate() {
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(((DataSourceTransactionManager)transactionManager()).getDataSource());
return jdbcTemplate;
}
#Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(getDataSource());
}
#Bean
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) {
final DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(databasePopulator());
return initializer;
}
private DatabasePopulator databasePopulator() {
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.addScript(schemaScript);
return populator;
}
#PostConstruct
public void setupDatabase() {
String url = "jdbc:mysql://localhost:3306";
try {
Connection connection = DriverManager.getConnection(url, settings.getUsername(), settings.getPassword());
Statement statement = connection.createStatement();
statement.execute("create database test");
} catch (SQLException exception) {
LOGGER.error("Could not setup database for test", exception);
throw new RuntimeException(exception);
}
}
}
I am getting the following error Caused by:
org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'test'
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80)
at org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:46)
Can someone explain what is going wrong with this configuration?
Did you create the test database at your local mysql? You need to create the db first to connect from your application. If you want to create a database by executing sql query connect to the database as root user and create the db.
The source of the exception: your setupDatabase() method is executed actually by Spring AFTER getDataSource() cause #Bean(initMethod = "setupDatabase") forces Spring to execute initMetod AFTER a bean creation for the bean initialization. But it's not you expect here.
You need somehow define your getDataSource() is depended on setupDatabase(). E.g. with a help of #DependsOn annotation.
Also see Spring 3 bean instantiation sequence
P.S. but why you don't simple manually add setupDatabase() call into getDataSource() method?
Spring Boot: 1.3.2.RELEASE
Vaadin : 7.6.3
Mysql: mysql-java-connector-5.1.38
HikariCP: 2.4.3
So I create a Table with only id and name columns. Then a vaadin componant Table to show the content of table. Until now everything is fine. Then I tried to filter the table with a vaadin Filter, and it works if the connection pool is com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPool, and doesnot if it is com.vaadin.data.util.sqlcontainer.connection.J2EEConnectionPool which I use HikariCP as the data source.
DBConfig.java
#Configuration
#EnableTransactionManagement
public class DatabaseConfig {
#Bean
public HikariConfig hikariConfig() {
HikariConfig config = new HikariConfig();
config.setDriverClassName("com.mysql.jdbc.Driver");
config.setJdbcUrl("jdbc:mysql://localhost:3306/test?autoReconnect=true&useSSL=false");
config.setUsername("root");
config.setPassword("root");
config.setMaximumPoolSize(20);
config.setPoolName("connectionPool");
return config;
}
#Bean
public DataSource dataSource() {
HikariDataSource dataSource = new HikariDataSource(hikariConfig());
return dataSource;
}
ApplicationUI.java
#Autowired
private J2EEConnectionPool connectionPool;
#Override
protected void init(VaadinRequest arg0) {
TableQuery tq = new TableQuery("medecine", connectionPool);// it does not work if I use HikariCP as the J2EEConnectionPool
JDBCConnectionPool pool = new SimpleJDBCConnectionPool("com.mysql.jdbc.Driver",
"jdbc:mysql://localhost:3306/test?autoReconnect=true&useSSL=false", "root", "root");
TableQuery tq = new TableQuery("medecine", connectionPool);// it works if I use **SimpleJDBCConnectionPool**.
container = new SQLContainer(tq);
table = new Table();
table.setContainerDataSource(container);
table.setWidth(100, Unit.PERCENTAGE);
mainLayout.addComponent(table);
Button addFilter = new Button("filter", new ClickListener() {
private static final long serialVersionUID = -7071683058766115266L;
#Override
public void buttonClick(ClickEvent arg0) {
Filter filter = new SimpleStringFilter("name", "medecine2", true, false);
container.addContainerFilter(filter);
}
});
mainLayout.addComponent(addFilter);
}
The reason I choose HikariCP as the data source is for a better performance and I'm not sure that the vaadin connection pool will be better than HikariCP. Or, it is limited to vaadin connection pool for the filtering function?