I implemented CRUD operations in Spring Boot. And everything works fine when I use ./gradlew bootRun
.
But when I run native image from ./gradlew clean nativeCompile
the operations which retrieve objects from DB are failing with:
org.postgresql.util.PSQLException: conversion to class java.time.Instant from timestamptz not supported
at org.postgresql.jdbc.PgResultSet.getObject(PgResultSet.java:3874) ~[na:na]
at com.zaxxer.hikari.pool.HikariProxyResultSet.getObject(HikariProxyResultSet.java) ~[na:na]
at org.springframework.jdbc.support.JdbcUtils.getResultSetValue(JdbcUtils.java:230) ~[na:na]
...
...
Caused by: java.lang.IllegalStateException: Cannot convert value of type 'java.sql.Timestamp' to required type 'java.time.Instant' for property 'createdOn': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:259)
at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:589)
Example findById
operation:
public Optional<ClientDto> findById(String tenantId, UUID id) {
List<ClientDto> result =
db.query(
"SELECT * FROM clients WHERE tenant_id = ? AND id = ?",
DataClassRowMapper.newInstance(ClientDto.class),
tenantId,
id);
return result.size() == 1 ? Optional.ofNullable(result.get(0)) : Optional.empty();
}
ClientDto
:
public record ClientDto(
UUID id,
String tenantId,
String name,
String description,
Instant createdOn,
Instant modifiedOn) {
}
I believe that some type converters are not initialized or not being found in the native image of my app, but I don't know how to fix it.
I tried to change DataClassRowMapper
to BeanPropertyRowMapper
and use normal class
instead of java record
, but result was the same.
I also tried to introduce my custom converter from sql.Timestamp
to time.Instant
, but it didn't work either.
When I change my repository implementation to use ListCRUDRepository
- it works.
When using RowMapper
instead of DataClassRowMapper
- it works.
I would like to use DataClassRowMapper
, but I don't know how to make it work.