Обсуждение: [JDBC] Timestamp parameter gets sent as date

Поиск
Список
Период
Сортировка

[JDBC] Timestamp parameter gets sent as date

От
Genya
Дата:

I'm facing quite weird situation working on pure JDBC Java code connected to Postgres DB.

The SQL used for PreparedStatement is relatively simple:

SELECT * FROM test t INNER JOIN ....

WHERE  t.id = ? AND (?::TIMESTAMP IS NULL OR t.date + t.time <= ?::TIMESTAMP WITHOUT TIME ZONE)

 

t.date is [date NOT NULL]
t.time is [time without time zone NOT NULL]

 

So, Java code to prepare and set parameters is as following:

PreparedStatement statement = connection.prepareStatement(SQL);
statement.setInt(1, id);

if (date== null) {
   statement.setNull(2, Types.DATE);
   statement.setNull(3, Types.DATE);
}
else {
   statement.setTimestamp(2, Timestamp.valueOf(date));
   statement.setTimestamp(3, Timestamp.valueOf(date));
}

ResultSet rs = statement.executeQuery();

 

The issue is: though Java code sets date parameters to PreparedStatement correctly (checked with logging) i.e. $1 = '29', $2 = '2017-01-14:13:00', $3 = '2017-01-14:13:00' , but actual query performed by PostgreSQL server (logging) SOMETIMES shows parameters used GMT DETAIL:  parameters: $1 = '29', $2 = '2017-01-14', $3 = '2017-01-14'.  Strangest thing that in 95% cases of same request with different params the output (behaviour and parameters) is correct, i.e. parameters are set and seen as DATE + TIME both from API and PostgreSQL. Moreover, repeteadly passing problematic parameters finally gets right query's behavior and output, sometimes after few tries or Java application restart. Worth mentioning, Java app does not do any "caching" or data modification - it's simple REST API for DB calls.

I'm not sure if it might be something very simple (JDBC/DB configuration) or a bug in postgres JDBC driver - since there is no other sofware to blame. Java code seemingly does everything right but PostgresSQL SOMETIMES receives different parameters (date instead of date + time).

I've tried to enable postgres JDBC driver logging as it's said in documentation but did not manage it to operate with Spring Boot logging.

 

 

JDBC driver used: 42.1.4 (latest)

Server version: 9.5

Other related software: HikariCP

 

 

 

Re: [JDBC] Timestamp parameter gets sent as date

От
Dave Cramer
Дата:


On 22 September 2017 at 06:43, Genya <genyap@online.ua> wrote:

I'm facing quite weird situation working on pure JDBC Java code connected to Postgres DB.

The SQL used for PreparedStatement is relatively simple:

SELECT * FROM test t INNER JOIN ....

WHERE  t.id = ? AND (?::TIMESTAMP IS NULL OR t.date + t.time <= ?::TIMESTAMP WITHOUT TIME ZONE)

 

t.date is [date NOT NULL]
t.time is [time without time zone NOT NULL]

 

So, Java code to prepare and set parameters is as following:

PreparedStatement statement = connection.prepareStatement(SQL); 

statement.setInt(1, id);

if (date== null) {

you are changing the type of the parameter here when you setNull Types.DATE. use Types.TIMESTAMP. 
 

   statement.setNull(2, Types.DATE);
   statement.setNull(3, Types.DATE);
}

else {
   statement.setTimestamp(2, Timestamp.valueOf(date));
   statement.setTimestamp(3, Timestamp.valueOf(date));
}

ResultSet rs = statement.executeQuery();

 

The issue is: though Java code sets date parameters to PreparedStatement correctly (checked with logging) i.e. $1 = '29', $2 = '2017-01-14:13:00', $3 = '2017-01-14:13:00' , but actual query performed by PostgreSQL server (logging) SOMETIMES shows parameters used GMT DETAIL:  parameters: $1 = '29', $2 = '2017-01-14', $3 = '2017-01-14'.  Strangest thing that in 95% cases of same request with different params the output (behaviour and parameters) is correct, i.e. parameters are set and seen as DATE + TIME both from API and PostgreSQL. Moreover, repeteadly passing problematic parameters finally gets right query's behavior and output, sometimes after few tries or Java application restart. Worth mentioning, Java app does not do any "caching" or data modification - it's simple REST API for DB calls.

I'm not sure if it might be something very simple (JDBC/DB configuration) or a bug in postgres JDBC driver - since there is no other sofware to blame. Java code seemingly does everything right but PostgresSQL SOMETIMES receives different parameters (date instead of date + time).

I've tried to enable postgres JDBC driver logging as it's said in documentation but did not manage it to operate with Spring Boot logging.




Re: [JDBC] Timestamp parameter gets sent as date

От
Vladimir Sitnikov
Дата:
>Debugger always has shown date parameter set as 2017-01-10 16:45:00+02 so time zone was present (though I don't use it)
>Still don't understand why it's happening SOMETIMES (not always), seems like a bug ?

Suppose the statement is "select function(?)".
In this case pgjdbc has no clue if backend wants "with time zone" or "without time zone".
This is why pgjdbc passes the timestamp as string with timezone info like "2017-01-10 16:45:00+02".
In case backend wants "with time zone" it uses the timezone from the string, and in case backend wants "without time zone" it just silently ignores the timezone.

Regarding "sometimes", I've no idea (yet).

>it does not log anything when the application is up. Is it Spring related ?

I've no idea. A reproducer would probably help to analyze the issue.

Vladimir