使用Postgres“无法确定参数$ 1的数据类型”

时间:2018-04-11 15:45:22

标签: spring-jdbc

我通过设置对postgres的时间戳绑定来面对这似乎是一个着名的问题。

@Test
public void testGetCurrentDate() {

    NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(datasources.get(dbType));

    PlatformTransactionManager manager = new DataSourceTransactionManager(datasources.get(dbType));

    final Timestamp ts = new Timestamp(System
            .currentTimeMillis());

    new TransactionTemplate(manager).execute(new TransactionCallbackWithoutResult() {

        @Override
        protected void doInTransactionWithoutResult(TransactionStatus status) {
            template.update("create table test_timestamp (col timestamp)", Collections.emptyMap());
            template.update("insert into test_timestamp (col) values (:TS) ", Collections.singletonMap("TS", ts));
        }
    });

    Assert.assertEquals((Integer) 1, new TransactionTemplate(manager).execute(new TransactionCallback<Integer>() {

        @Override
        public Integer doInTransaction(TransactionStatus status) {
            MapSqlParameterSource paramsSource = new MapSqlParameterSource();
            paramsSource.addValue("TS", ts, Types.TIMESTAMP, "timestamp");

            return template.queryForObject("select 1 from test_timestamp where :TS is not null and col=:TS ", paramsSource,
                    Integer.class);

        }
    }));

}

此测试失败,错误:无法确定参数$ 1的数据类型

在这里看到与postgres有关的讨论: http://www.postgresql-archive.org/quot-could-not-determine-data-type-of-parameter-quot-with-timestamp-td5995489.html

我已经有了解决方法(设置PGTimestamp实例而不是Timestamp)。我想知道它是否有助于Spring JDBC提高多个数据库的可移植性。

在这种情况下,org.springframework.jdbc.core.StatementCreatorUtils(第380行附近)的解决方法是这样的:

else if (sqlType == Types.TIMESTAMP &&
"PostgreSQL".equals(ps.getConnection().getMetaData().getDatabaseProductName()))) {

            Class<?> pgTimestampClass = Class.forName("org.postgresql.util.PGTimestamp");
            Timestamp ts = (Timestamp)pgTimestampClass.getConstructor(long.class).newInstance(javaValue.getTime());
            ps.setTimestamp(paramIndex, ts);

如果您认为它有意义,我可以提出拉取请求。

Arnaud

0 个答案:

没有答案