web-dev-qa-db-fra.com

Comment configurer une source de données avec Spring for HikariCP?

Bonjour, j'essaie d'utiliser HikariCP avec Spring pour le pool de connexion. J'utilise jdbcTempLate et JdbcdaoSupport.
Voici mon fichier de configuration de printemps pour la source de données:

<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
    <property name="dataSourceClassName" value="Oracle.jdbc.driver.OracleDriver"/>
    <property name="dataSource.url" value="jdbc:Oracle:thin:@localhost:1521:XE"/>
    <property name="dataSource.user" value="username"/>
    <property name="dataSource.password" value="password"/>
</bean>

Mais malheureusement, le message d'erreur suivant est généré:

Cannot resolve reference to bean 'dataSource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in ServletContext resource [/WEB-INF/dispatcher-servlet.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.zaxxer.hikari.HikariDataSource]: No default constructor found; nested exception is Java.lang.NoSuchMethodException: com.zaxxer.hikari.HikariDataSource.<init>()

Quelqu'un peut-il me dire comment résoudre ce problème?

36
Abhinab Kanrar

vous devez écrire cette structure sur votre configuration de bean (c'est votre source de données):

<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
    <property name="poolName" value="springHikariCP" />
    <property name="connectionTestQuery" value="SELECT 1" />
    <property name="dataSourceClassName" value="${hibernate.dataSourceClassName}" />
    <property name="maximumPoolSize" value="${hibernate.hikari.maximumPoolSize}" />
    <property name="idleTimeout" value="${hibernate.hikari.idleTimeout}" />

    <property name="dataSourceProperties">
        <props>
            <prop key="url">${dataSource.url}</prop>
            <prop key="user">${dataSource.username}</prop>
            <prop key="password">${dataSource.password}</prop>
        </props>
    </property>
</bean>

<!-- HikariCP configuration -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
    <constructor-arg ref="hikariConfig" />
</bean>

Ceci est mon exemple et ça marche. Il vous suffit de mettre vos propriétés sur hibernate.properties et de les définir avant:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:hibernate.properties</value>
        </list>
    </property>
</bean>

Obs .: les versions sont
log4j: 1.2.16
Springframework: 3.1.4.LELEASE
HikariCP: 1.4.0

Fichier de propriétés (hibernate.properties):

hibernate.dataSourceClassName=Oracle.jdbc.pool.OracleDataSource
hibernate.hikari.maximumPoolSize=10
hibernate.hikari.idleTimeout=30000
dataSource.url=jdbc:Oracle:thin:@localhost:1521:xe
dataSource.username=admin
dataSource.password=
32
bpedroso

mon test Java config (pour MySql)

@Bean(destroyMethod = "close")
public DataSource dataSource(){
    HikariConfig hikariConfig = new HikariConfig();
    hikariConfig.setDriverClassName("com.mysql.jdbc.Driver");
    hikariConfig.setJdbcUrl("jdbc:mysql://localhost:3306/spring-test"); 
    hikariConfig.setUsername("root");
    hikariConfig.setPassword("admin");

    hikariConfig.setMaximumPoolSize(5);
    hikariConfig.setConnectionTestQuery("SELECT 1");
    hikariConfig.setPoolName("springHikariCP");

    hikariConfig.addDataSourceProperty("dataSource.cachePrepStmts", "true");
    hikariConfig.addDataSourceProperty("dataSource.prepStmtCacheSize", "250");
    hikariConfig.addDataSourceProperty("dataSource.prepStmtCacheSqlLimit", "2048");
    hikariConfig.addDataSourceProperty("dataSource.useServerPrepStmts", "true");

    HikariDataSource dataSource = new HikariDataSource(hikariConfig);

    return dataSource;
}
26
Yura

Vous pouvez créer un bean source de données dans un contexte de servlet en tant que:

<beans:bean id="dataSource"
    class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
    <beans:property name="dataSourceClassName"
        value="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" />
    <beans:property name="maximumPoolSize" value="5" />
    <beans:property name="maxLifetime" value="30000" />
    <beans:property name="idleTimeout" value="30000" />
    <beans:property name="dataSourceProperties">
        <beans:props>
            <beans:prop key="url">jdbc:mysql://localhost:3306/exampledb</beans:prop>
            <beans:prop key="user">root</beans:prop>
            <beans:prop key="password"></beans:prop>
            <beans:prop key="prepStmtCacheSize">250</beans:prop>
            <beans:prop key="prepStmtCacheSqlLimit">2048</beans:prop>
            <beans:prop key="cachePrepStmts">true</beans:prop>
            <beans:prop key="useServerPrepStmts">true</beans:prop>
        </beans:props>
    </beans:property>
</beans:bean>
6
Shahid Yousuf

En utilisant la configuration XML, votre source de données devrait ressembler à ceci:

    <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">  
      <property name="dataSourceProperties" >
        <props>
            <prop key="dataSource.url">jdbc:Oracle:thin:@localhost:1521:XE</prop>
            <prop key="dataSource.user">username</prop>
            <prop key="dataSource.password">password</prop>
        </props>
      </property>  
      <property name="dataSourceClassName"   
                value="Oracle.jdbc.driver.OracleDriver" />  
    </bean>  

    <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">  
          <constructor-arg ref="hikariConfig" />  
    </bean>  

Vous pouvez également ignorer le bean HikariConfig et utiliser une approche semblable à celle mentionnée ici

3
geoand

J'ai récemment migré de C3P0 to HikariCP dans un projet basé sur Spring and Hibernate et ce n’était pas aussi facile que je l’avais imaginé et je partage ici mes découvertes.

Pour Spring Boot voir ma réponse ici

J'ai la configuration suivante

  • Printemps 4.3.8+
  • Hiberante 4.3.8+
  • Gradle 2.x
  • PostgreSQL 9.5

Certaines des configurations ci-dessous sont similaires à certaines des réponses ci-dessus, mais il existe des différences.

Gradle stuff

Afin de tirer dans les bons pots, je devais tirer les pots suivants

//latest driver because *brettw* see https://github.com/pgjdbc/pgjdbc/pull/849
compile 'org.postgresql:postgresql:42.2.0'
compile('com.zaxxer:HikariCP:2.7.6') {
    //they are pulled in separately elsewhere
    exclude group: 'org.hibernate', module: 'hibernate-core'
}

// Recommended to use HikariCPConnectionProvider by Hibernate in 4.3.6+    
compile('org.hibernate:hibernate-hikaricp:4.3.8.Final') {
        //they are pulled in separately elsewhere, to avoid version conflicts
        exclude group: 'org.hibernate', module: 'hibernate-core'
        exclude group: 'com.zaxxer', module: 'HikariCP'
}

// Needed for HikariCP logging if you use log4j
compile('org.slf4j:slf4j-simple:1.7.25')  
compile('org.slf4j:slf4j-log4j12:1.7.25') {
    //log4j pulled in separately, exclude to avoid version conflict
    exclude group: 'log4j', module: 'log4j'
}

Configuration basée sur Spring/Hibernate

Pour que Spring & Hibernate utilise le pool Hikari Connection, vous devez définir le HikariDataSource et le nourrir dans le bean sessionFactory comme indiqué ci-dessous.

<!-- HikariCP Database bean -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
    <constructor-arg ref="hikariConfig" />
</bean>

<!-- HikariConfig config that is fed to above dataSource -->
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
        <property name="poolName" value="SpringHikariPool" />
        <property name="dataSourceClassName" value="org.postgresql.ds.PGSimpleDataSource" />
        <property name="maximumPoolSize" value="20" />
        <property name="idleTimeout" value="30000" />

        <property name="dataSourceProperties">
            <props>
                <prop key="serverName">localhost</prop>
                <prop key="portNumber">5432</prop>
                <prop key="databaseName">dbname</prop>
                <prop key="user">dbuser</prop>
                <prop key="password">dbpassword</prop>
            </props>
        </property>
</bean>

<bean class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" id="sessionFactory">
        <!-- Your Hikari dataSource below -->
        <property name="dataSource" ref="dataSource"/>
        <!-- your other configs go here -->
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.connection.provider_class">org.hibernate.hikaricp.internal.HikariCPConnectionProvider</prop>
                <!-- Remaining props goes here -->
            </props>
        </property>
 </bean>

Une fois que les éléments ci-dessus sont configurés, vous devez ajouter une entrée à votre log4j or logback et définissez level sur DEBUG pour voir le démarrage de Hikari pool de connexions.

Log4j1.2

<!-- Keep additivity=false to avoid duplicate lines -->
<logger additivity="false" name="com.zaxxer.hikari">
    <level value="debug"/>
    <!-- Your appenders goes here -->
</logger>

Logback

Via application.properties dans Spring Boot

debug=true
logging.level.com.zaxxer.hikari.HikariConfig=DEBUG 

En utilisant logback.xml

<logger name="com.zaxxer.hikari" level="DEBUG" additivity="false">
    <appender-ref ref="STDOUT" />
</logger>

Avec ce qui précède, vous devriez être tous prêts à partir! Il est évident que vous devez personnaliser les configurations de pool HikariCP afin d’obtenir les performances promises.

2
Raf

Cette dernière erreur est due à l'absence de la bibliothèque SLF4J. HikariCP a deux dépendances: slf4j et javassist. BTW, HikariDataSource a un constructeur par défaut et ne nécessite pas HikariConfig, voir ce lien . Donc ça n’a jamais été le problème.

2
brettw

pour DB2, veuillez essayer la configuration ci-dessous.

<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
    <property name="poolName" value="springHikariCP" />
    <property name="dataSourceClassName" value="com.ibm.db2.jcc.DB2SimpleDataSource"/>

    <property name="maximumPoolSize" value="${db.maxTotal}" />
    <property name="dataSourceProperties">
        <props>
            <prop key="driverType">4</prop>
            <prop key="serverName">192.168.xxx.xxx</prop>
            <prop key="databaseName">dbname</prop>
            <prop key="portNumber">50000</prop>
            <prop key="user">db2inst1</prop>
            <prop key="password">password</prop>
        </props>
    </property>

    <property name="jdbcUrl" value="${db.url}" />
    <property name="username" value="${db.username}" />
    <property name="password" value="${db.password}" />
</bean>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
    <constructor-arg ref="hikariConfig" />
</bean>
0
stanicmail

Je l'ai trouvé dans http://www.baeldung.com/hikaricp et cela fonctionne.

Votre pom.xml

<dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>2.6.3</version>
        </dependency>

Votre data.xml

<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="jdbcUrl" value="${jdbc.databaseurl}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
    <constructor-arg ref="hikariConfig" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
      p:dataSource-ref="dataSource"
/>

Votre jdbc.properties

jdbc.driverClassName=org.postgresql.Driver
jdbc.dialect=org.hibernate.dialect.PostgreSQL94Dialect
jdbc.databaseurl=jdbc:postgresql://localhost:5432/dev_db
jdbc.username=dev
jdbc.password=dev