问题
I want to configure HinkariCP data source with Spring4 Java config. My config looks like:
@Configuration
@EnableJpaRepositories("com.app.dao.repository")
@EnableTransactionManagement
public class DataAccessConfig {
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
private static final String PROPERTY_NAME_H_CONNECTION_PROVIDER = "hibernate.connection.provider_class";
@Autowired
private Environment env;
@Bean(destroyMethod = "close")
public HikariDataSource dataSource() {
HikariDataSource ds = new HikariDataSource();
ds.setMaximumPoolSize(100);
ds.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");
ds.addDataSourceProperty("url", "jdbc:mysql://127.0.0.1:3306/mydb?useUnicode=true&characterEncoding=UTF-8&transformedBitIsBoolean=true");
ds.addDataSourceProperty("user", "usr");
ds.addDataSourceProperty("password", "pwd");
ds.addDataSourceProperty("cachePrepStmts", true);
ds.addDataSourceProperty("prepStmtCacheSize", 250);
ds.addDataSourceProperty("prepStmtCacheSqlLimit", 2048);
ds.addDataSourceProperty("useServerPrepStmts", true);
return ds;
}
@Bean
@Autowired
public PlatformTransactionManager transactionManager() throws ClassNotFoundException {
return new JpaTransactionManager(entityManagerFactory().getObject());
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws ClassNotFoundException {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPackagesToScan("com.app.dao.entity");
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter());
entityManagerFactoryBean.setJpaDialect(new FlushModeCommitHibernateJpaDialect(FlushMode.COMMIT));
Properties jpaProperties = new Properties();
jpaProperties.put(PROPERTY_NAME_HIBERNATE_DIALECT,
env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
jpaProperties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL,
env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
jpaProperties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL,
env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
jpaProperties.put(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO,
env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO));
jpaProperties.put(PROPERTY_NAME_H_CONNECTION_PROVIDER,
env.getRequiredProperty(PROPERTY_NAME_H_CONNECTION_PROVIDER));
entityManagerFactoryBean.setJpaProperties(jpaProperties);
entityManagerFactoryBean.afterPropertiesSet();
return entityManagerFactoryBean;
}
@Bean
public SharedEntityManagerBean sharedEntityManager() throws ClassNotFoundException {
SharedEntityManagerBean sharedEntityManagerBean = new SharedEntityManagerBean();
sharedEntityManagerBean.setEntityManagerFactory(entityManagerFactory().getObject());
return new SharedEntityManagerBean();
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
AbstractJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
jpaVendorAdapter.setDatabasePlatform(env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
jpaVendorAdapter.setShowSql(env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL, Boolean.class));
return jpaVendorAdapter;
}
but i get an exception:
Caused by: java.lang.IllegalArgumentException: one of either dataSource or dataSourceClassName must be specified
at com.zaxxer.hikari.HikariConfig.validate(HikariConfig.java:683)
at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:75)
at com.zaxxer.hikari.hibernate.HikariConnectionProvider.configure(HikariConnectionProvider.java:80)
... 86 more
Can someone help my to configure HikariCP with Spring4, Hibernate and MySql Tech used: Java 8, Spring 4.1.0.RELEASE, Hibernate 4.3.6.Final, HikariCP 2.0.1
回答1:
The fact that you are calling entityManagerFactoryBean.setDataSource(dataSource())
should mean that you do not need to call jpaProperties.put(PROPERTY_NAME_H_CONNECTION_PROVIDER, env.getRequiredProperty(PROPERTY_NAME_H_CONNECTION_PROVIDER))
. You are mixing two styles of initialization. The stacktrace that originates with:
com.zaxxer.hikari.hibernate.HikariConnectionProvider.configure(HikariConnectionProvider.java:80)
is coming from the jpaProperties
initializing HikariCP itself (ignoring the DataSource that you set explicitly). The connection provider expects that HikariCP properties have been set in hibernate.properties
, as documented here.
By the way, Hibernate 4.3.6 now includes it own HikariCP ConnectionProvider, so if you use that it should be in preference to the one provided by HikariCP.
回答2:
try to comment line
//hikariConfig.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");
and add
hikariConfig.setDriverClassName("com.mysql.jdbc.Driver");
回答3:
I have already posted an answer to another question on how to configure HikariCP
with Spring Boot Start JPA
and if you were to rely on application.properties
and Spring Boot
to auto-configure everything for you then you need to name your key values in the application.properties
as follow
# Spring data source needed for Spring boot to behave
# Pre Spring Boot v2.0.0.M6 without below Spring Boot defaults to tomcat-jdbc connection pool included
# in spring-boot-starter-jdbc and as compiled dependency under spring-boot-starter-data-jpa
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.url=jdbc:postgresql://localhost:5432/somedb
spring.datasource.username=dbuser
spring.datasource.password=dbpassword
# Hikari will use the above plus the following to setup connection pooling
spring.datasource.hikari.minimumIdle=5
spring.datasource.hikari.maximumPoolSize=20
spring.datasource.hikari.idleTimeout=30000
spring.datasource.hikari.poolName=SpringBootJPAHikariCP
spring.datasource.hikari.maxLifetime=2000000
spring.datasource.hikari.connectionTimeout=30000
# Without below HikariCP uses deprecated com.zaxxer.hikari.hibernate.HikariConnectionProvider
# Surprisingly enough below ConnectionProvider is in hibernate-hikaricp dependency and not hibernate-core
# So you need to pull that dependency but, make sure to exclude it's transitive dependencies or you will end up
# with different versions of hibernate-core
spring.jpa.hibernate.connection.provider_class=org.hibernate.hikaricp.internal.HikariCPConnectionProvider
# JPA specific configs
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.use_sql=true
spring.jpa.properties.hibernate.id.new_generator_mappings=false
spring.jpa.properties.hibernate.default_schema=dbschema
spring.jpa.properties.hibernate.search.autoregister_listeners=false
spring.jpa.properties.hibernate.bytecode.use_reflection_optimizer=false
See how the properties key/values are named. For a full details on the properties and how you should setup your dependencies, see my answer to this SO question.
来源:https://stackoverflow.com/questions/25958750/configuration-hikaricp-spring4-hibernate