配置HikariCP + Spring4 + Hibernate

时间:2014-09-21 11:33:11

标签: spring hibernate java-8 hikaricp

我想用Spring4 Java配置配置HinkariCP数据源。 我的配置如下:

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

但我得到一个例外:

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

有人可以帮我配置Spring4,Hibernate和MySql的HikariCP 使用的技术:Java 8,Spring 4.1.0.RELEASE,Hibernate 4.3.6.Final,HikariCP 2.0.1

3 个答案:

答案 0 :(得分:0)

您致电entityManagerFactoryBean.setDataSource(dataSource())的事实应该意味着您无需致电jpaProperties.put(PROPERTY_NAME_H_CONNECTION_PROVIDER, env.getRequiredProperty(PROPERTY_NAME_H_CONNECTION_PROVIDER))。您正在混合两种初始化方式。源自:

的堆栈跟踪
com.zaxxer.hikari.hibernate.HikariConnectionProvider.configure(HikariConnectionProvider.java:80)

来自jpaProperties初始化HikariCP本身(忽略您明确设置的DataSource)。连接提供程序期望HikariCP属性已在hibernate.properties中设置,如文档here所示。

顺便说一句,Hibernate 4.3.6现在包含了它自己的HikariCP ConnectionProvider,所以如果你使用它,它应该优先于HikariCP提供的那个。

答案 1 :(得分:0)

尝试评论一下

//hikariConfig.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");

并添加

hikariConfig.setDriverClassName("com.mysql.jdbc.Driver");

答案 2 :(得分:0)

我已经发布了关于如何使用HikariCP配置Spring Boot Start JPA的另一个问题的答案,如果您依靠application.propertiesSpring Boot自动配置所有内容对于您,您需要在application.properties中为您的键值命名,如下所示

# 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 

查看属性键/值的命名方式。有关属性以及如何设置依赖项的完整详细信息,请参阅我对此SO question的回答。