在Spring Boot中,将c3p0与jdbcTemplate和Hibernate同时使用

Jim*_*her 4 hibernate jdbc c3p0 spring-boot

我有一个SpringBoot应用程序(在Java 8上为1.3.2RELEASE),它同时使用Hibernate 4.3.11.Final和SQL调用通过JDBC对Oracle JDBC驱动程序12.0.1.1。它还使用hibernate-c3p0 4.3.11.Final。JDBC调用是针对自动装配的JdbcTemplate实例进行的。

在pom中,我还具有Oracle UCP和ONS的依赖关系。以下是相关的pom条目:

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-c3p0</artifactId>
        <version>4.3.11.Final</version>
    </dependency>
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc7</artifactId>
        <version>12.1.0.1</version>
    </dependency>

    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ucp</artifactId>
        <version>12.1.0.2</version>
    </dependency>
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ons</artifactId>
        <version>12.1.0.2</version>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

但是,我找不到Oracle UCP的配置。同样,c3p0的所有配置似乎仅适用于Hibernate。

以下是相关的application.properties文件条目(没有其他属性文件):

# Properties for Hibernate and Oracle
spring.datasource.driverClassName=oracle.jdbc.driver.OracleDriver
spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
spring.jpa.properties.hibernate.connection.driver_class = oracle.jdbc.driver.OracleDriver

spring.datasource.url=jdbc:oracle:thin:@my-db-server:1523:me
spring.datasource.username=myuser
spring.datasource.password=mypass


# Configure the C3P0 database connection pooling module
spring.jpa.properties.hibernate.c3p0.max_size = 15
spring.jpa.properties.hibernate.c3p0.min_size = 6
spring.jpa.properties.hibernate.c3p0.timeout = 2500
spring.jpa.properties.hibernate.c3p0.max_statements_per_connection = 10
spring.jpa.properties.hibernate.c3p0.idle_test_period = 3000
spring.jpa.properties.hibernate.c3p0.acquire_increment = 3
spring.jpa.properties.hibernate.c3p0.validate = false
spring.jpa.properties.hibernate.c3p0.numHelperThreads = 15

spring.jpa.properties.hibernate.connection.provider_class = org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.Oracle10gDialect

spring.jpa.properties.hibernate.connection.url=jdbc:oracle:thin:@sea-db-server:1523:me
spring.jpa.properties.hibernate.connection.username=myuser
spring.jpa.properties.hibernate.connection.password=mypass
Run Code Online (Sandbox Code Playgroud)

我想弄清楚的是,针对spring自动接线的JdbcTemplate进行的JDBC调用是否正在使用c3p0连接池,以及Oracle UCP是否正在做任何事情,因为它似乎没有配置。

我确实需要JDBC调用的连接池。现在,我遇到了一个问题,即与Oracle的连接已关闭。我们没有使用Oracle RAC,所以我不需要UCP,因此可以只使用c3p0。

如果有人可以帮助我了解现在的情况,或者告诉我要检查的内容,我将不胜感激。另外,假设我是对的,并且JDBC调用未使用池,那么解决此问题的最佳方法是什么?

更新

根据下面的答案和评论,我决定删除c3p0并使用Spring本身支持的池。因此,我将c3p0从pom中拉出(以及oracle ucp和ons),并在application.properties文件中包含以下内容。

我试图确保(1)我有一个连接池,该连接池将在连接丢失时管理与数据库的重新连接;(2)JDBC和Hibernate使用的是相同的数据源。

我说对了吗?

spring.datasource.url=jdbc:oracle:thin:@db-server:1523:mysvc
spring.datasource.username=myuser
spring.datasource.password=mypass

spring.datasource.max-active=50
spring.datasource.initial-size=5
spring.datasource.max-idle=10
spring.datasource.min-idle=5
spring.datasource.test-while-idle=true
spring.datasource.test-on-borrow=true
spring.datasource.validation-query=SELECT 1 FROM DUAL
spring.datasource.time-between-eviction-runs-millis=5000
spring.datasource.min-evictable-idle-time-millis=60000
Run Code Online (Sandbox Code Playgroud)

Ste*_*oll 5

看来您正在尝试通过Hibernate创建连接池。Spring Boot自动创建一个DataSource绑定到Hibernate的,但是您(spring.jpa.properties.hibernate.spring.jpa.properties.hibernate.connection.url)的配置正在创建另一个 DataSource!

如果您依赖自动配置JdbcTemplate,则不应要求休眠来创建DataSource(没有理由我们应该重复使用它)。我不知道该特定功能,但我会执行以下操作:

  1. 删除所有spring.jpa.properties.hibernate.c3p0spring.jpa.properties.hibernate.connection.url碎片
  2. 依靠Spring Boot创建DataSource。我们不支持c3p0(也许应该吗?)。如果要使用它,可以创建自己的
  3. 删除所有方言内容,无论如何我们都会自动为您检测

这是创建DataSource并将其绑定到环境的简单方法

@Bean
@ConfigurationProperties("yourapp.datasource")
public ComboPooledDataSource dataSource() {
    return new ComboPooledDataSource();
}
Run Code Online (Sandbox Code Playgroud)

然后在您的配置中,您可以添加类似

yourapp.datasource.driver-class=oracle.jdbc.driver.OracleDriver
yourapp.datasource.jdbc-url=jdbc:oracle:thin:@sea-db-server:1523:me
...
yourapp.datasource.min-pool-size=6
yourapp.datasource.max-pool-size=15
...
Run Code Online (Sandbox Code Playgroud)