spring-projects / spring-projects/spring-data-relational
Same type (java.sql.Timestamp) turns into different SQL-types
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 827
- Forks
- 394
- PR merge metrics
- No merged PRs in 30d
Description
Hello, I am not sure where this happens, but I am having some trouble with ZonedDateTime.
I have read in the documentation that ZonedDateTime is not supported (https://docs.spring.io/spring-data/jdbc/docs/current/reference/html/#jdbc.entity-persistence.types), therefore I wrote a converter (ZonedDateTime -> java.sql.Timestamp).
I have the following data class:
data class OrderLineEvent(
(...) other fields
val orderLineEventType: String? = null,
val travelDate: ZonedDateTime? = null,
val timestamp: LocalDateTime = LocalDateTime.now() // Actually a ZonedDateTime, but using LocalDateTime for illustration purposes
) {
}
Converter:
import java.sql.Timestamp
import java.time.ZoneOffset
import java.time.ZonedDateTime
@Configuration
@EnableJdbcRepositories
class DataJdbcConfiguration : AbstractJdbcConfiguration() {
@WritingConverter
class ZonedDateTimeWriterConverter : Converter<ZonedDateTime, Timestamp> {
override fun convert(date: ZonedDateTime): Timestamp {
return Timestamp.valueOf(date.withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime())
}
}
@Bean
override fun jdbcCustomConversions(): JdbcCustomConversions {
return JdbcCustomConversions(listOf(ZonedDateTimeWriterConverter()))
}
}
Repository:
@Repository
interface OrderLineEventRepository : CrudRepository<OrderLineEvent, Long>
Ok, here is the issue: I am unable to save this as a timestamp. The error is Translating SQLException with SQL state '42804', error code '0', message [ERROR: column "travel_date" is of type timestamp without time zone but expression is of type character varying which is quite odd.
After investigating this further (and enabling TRACE-logging), it seems like the parameter gets converted into a VARCHAR/string type(?) AND a different type than the `LocalDateTime
Look at logs below:
o.s.jdbc.core.StatementCreatorUtils : Setting SQL statement parameter value: column index 11, parameter value [123.42], value class [java.lang.String], SQL type 12
o.s.jdbc.core.StatementCreatorUtils : Setting SQL statement parameter value: column index 12, parameter value [2021-11-17 08:31:28.731541], value class [java.sql.Timestamp], SQL type 93
o.s.jdbc.core.StatementCreatorUtils : Setting SQL statement parameter value: column index 13, parameter value [2021-11-17 08:31:28.73009], value class [java.sql.Timestamp], SQL type 12
It seems like String and ZonedDateTime turns into the same SQL type.
String -> java.lang.String, SQL type 12
LocalDateTime -> java.sql.Timestamp, SQL type 93
ZonedDateTime -> java.sql.Timestamp, SQL type 12
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the ZonedDateTimeWriterConverter in DataJdbcConfiguration and trace the parameter handling shown by StatementCreatorUtils. Reproduce the OrderLineEvent save and compare the logged SQL types for ZonedDateTime and LocalDateTime; done means the converted ZonedDateTime binds as a timestamp without time zone rather than as a VARCHAR.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- backend, database
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100