HikariCP:5 次查询后,Postgres timestamptz 列时区在 PreparedStatement 的结果集中消失

HikariCP: Postgres timestamptz column timezone disappears in resultset of PreparedStatement after 5 queries

我在 play2.4 中的光滑映射不起作用,我将问题归结为:如果我从 table 和 timestamp with time zone 做一个简单的 select列,时区会在一段时间后从结果中消失。此消息末尾的示例产生以下输出: 2015-10-27 20:45:13.459+01 2015-10-27 20:45:13.459+01 2015-10-27 20:45:13.459+01 2015-10-27 20:45:13.459+01 2015-10-27 20:45:13.459+01 // from now on, the timezone is never returned (even after 1000 queries) 2015-10-27 20:45:13.459 2015-10-27 20:45:13.459 2015-10-27 20:45:13.459 2015-10-27 20:45:13.459 ...

我尝试了普通版和 java6 版的 hikaricp。 我正在使用 postgres 9.4。我在 scala 工作,但我在 java 中创建了示例以扩大受众 ;)

我打开了一个问题,但我有点匆忙所以如果有人知道该怎么做...... 如果有人能告诉我如何在 play 2.4 中使用 bonecp 或其他任何东西,我也将不胜感激。

您可以使用仅包含 HikariCP 和 postgres 依赖项的项目重现该问题:

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class TestHikari {
    public static void main(String[] args) throws Exception {
        HikariConfig conf = new HikariConfig();
        conf.setJdbcUrl("jdbc:postgresql://localhost/postgres");
        conf.setDriverClassName("org.postgresql.Driver");

        HikariDataSource ds = new HikariDataSource(conf);
        Connection ddlconn = ds.getConnection();
        try { ddlconn.createStatement().execute("DROP TABLE TEST"); } catch(Exception ignored) {}
        ddlconn.createStatement().execute("CREATE TABLE TEST (ts TIMESTAMP with time zone)");
        ddlconn.createStatement().execute("insert into test(ts) values('2015-10-27 20:45:13.459+01')");
        ddlconn.close();

        for (int i = 0; i< 10; i++) {
            Connection conn = ds.getConnection();
            PreparedStatement stmt = conn.prepareStatement("select ts from TEST");
            //if I uncomment the next line, it works!
            //conn.prepareStatement("select ts from TEST");
            ResultSet rs = stmt.executeQuery();
            rs.next();

            System.out.println(rs.getString(1));

            conn.close();
        }
    }
}

这里已经回答了这个问题:https://github.com/brettwooldridge/HikariCP/issues/473

There were some issues with dates / timezones when the JDBC driver switches to server-side prepared statements. By default this happens after 5 prepared statement executions (see prepareThreshold parameter of postgresql JDBC).

所以这是 postgres jdbc 驱动程序中的错误。似乎目前唯一的解决方法是设置 prepareThreshold=0 或切换到没有时区的时间戳。