Method org.postgresql.jdbc4.Jdbc4Connection.isValid(int) is not yet implemented

janetsmith picture janetsmith · Aug 31, 2014 · Viewed 39.4k times · Source

I am trying to configure dbcp2 with postgres 9.1

When I run my app, it throws exception:

Exception in thread "main" org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: Cannot create PoolableConnectionFactory (Method org.postgresql.jdbc4.Jdbc4Connection.isValid(int) is not yet implemented.)
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:575)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:639)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:664)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:704)
    at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForObject(NamedParameterJdbcTemplate.java:195)
    at com.springinpractice.ch02.service.impl.ContactServiceImpl.getContact(ContactServiceImpl.java:64)
    at com.springinpractice.ch02.ConsoleApp.main(ConsoleApp.java:16)
Caused by: java.sql.SQLException: Cannot create PoolableConnectionFactory (Method org.postgresql.jdbc4.Jdbc4Connection.isValid(int) is not yet implemented.)
    at org.apache.commons.dbcp2.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:2152)
    at org.apache.commons.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:1903)
    at org.apache.commons.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1413)
    at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111)
    at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77)
    ... 7 more
Caused by: org.postgresql.util.PSQLException: Method org.postgresql.jdbc4.Jdbc4Connection.isValid(int) is not yet implemented.
    at org.postgresql.Driver.notImplemented(Driver.java:753)
    at org.postgresql.jdbc4.AbstractJdbc4Connection.isValid(AbstractJdbc4Connection.java:109)
    at org.postgresql.jdbc4.Jdbc4Connection.isValid(Jdbc4Connection.java:21)
    at org.apache.commons.dbcp2.DelegatingConnection.isValid(DelegatingConnection.java:914)
    at org.apache.commons.dbcp2.PoolableConnection.validate(PoolableConnection.java:227)
    at org.apache.commons.dbcp2.PoolableConnectionFactory.validateConnection(PoolableConnectionFactory.java:303)
    at org.apache.commons.dbcp2.BasicDataSource.validateConnectionFactory(BasicDataSource.java:2165)
    at org.apache.commons.dbcp2.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:2148)
    ... 11 more

Here is my maven POM:

<dependencies>
    <!-- Spring and Transactions -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring-framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring-framework.version}</version>
    </dependency>

    <!-- Logging with SLF4J & LogBack -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j.version}</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>${logback.version}</version>
        <scope>runtime</scope>
    </dependency>

    <!-- Hibernate -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>${hibernate.version}</version>
    </dependency>


    <!-- Test Artifacts -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${spring-framework.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
    </dependency>

    <!-- For JDBC -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring-framework.version}</version>
    </dependency>

    <dependency>
        <groupId>postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.1-901.jdbc4</version>

    </dependency>

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-dbcp2</artifactId>
        <version>2.0.1</version>
    </dependency>
    <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
    </dependency>

</dependencies>

Answer

Craig Ringer picture Craig Ringer · Sep 1, 2014

That method is implemented in the current driver version. You must be using an old PgJDBC. Upgrade. It's fully backward compatible. (You should've specified your PgJDBC version in the question).

Separately, though, relying on connection "validation" is usually a bad idea. It's just a way of trying to imperfectly hide a race condition. Simply grab the connection and use it. If there's a problem with it, your application should trap the resulting exception, check the SQLSTATE to see if it's a connection related error, and retry with a new connection.