Problemas al convertir entre java.sql.Timestamp y java.time.Instant con JOOQ
Tengo problemas para convertir entre java.sql.Timestamp y java.time.Instant utilizando los conversores de JOOQ.
Aquí hay una versión simplificada del código con el que estoy trabajando.
public class User {
private static final Converter<timestamp, instant=""> MY_CONVERTER = Converter.of(
Timestamp.class,
Instant.class,
t -> t == null ? null : t.toInstant(),
i -> i == null ? null : Timestamp.from(i)
);
public static Table<?> table = DSL.table("user");
public static Field<string> name = DSL.field(DSL.name(table.getName(), "name"), String.class);
public static Field<instant> created = DSL.field(DSL.name(table.getCreated(), "created"), SQLDataType.TIMESTAMP.asConvertedDataType(Converter.of(MY_CONVERTER)));
}
private class UserDto {
private String name;
private Instant created;
// getters, setters, etc.
}
public class UserWriter {
// constructor with injected DefaultDSLContext etc..
public void create(UserDto user) {
dslContext.insertInto(User.table, User.name, User.created)
.values(user.getName(), user.getCreated())
.execute();
}
}
public class UserReader {
// constructor with injected DefaultDSLContext etc..
public Result<record> getAll() {
return dslContext.select().from(User.table).fetch();
}
}
public class UserService {
// constructor with injected UserReader etc..
public Collection<userdto> getAll() {
return userReader
.getAll()
.stream()
.map(Users::from)
.collect(Collectors.toList());
}
}
public class Users {
public static UserDto from(Record record) {
UserDto user = new UserDto();
user.setName(record.get(User.name));
user.setCreated(record.get(User.created));
return user;
}
}
Cuando creo un nuevo usuario, el convertidor es llamado y la inserción funciona correctamente. Sin embargo, cuando selecciono los usuarios, el convertidor no es llamado y la llamada record.get(User.created)
en el método Users::from
devuelve un Timestamp (y por lo tanto falla ya que UserDto.setCreated espera un Instant).
¿Alguna idea?
¡Gracias!</timestamp,>
davy.ai
Parece que el problema es causado por no usar el Campo convertido al seleccionar datos de la base de datos. En la clase
User
, el Camponame
se crea utilizando un tipo de dato convertido (SQLDataType.TIMESTAMP.asConvertedDataType(Converter.of(MY_CONVERTER))
), pero esto no se está haciendo para el Campocreated
.Para solucionar esto, puedes crear un Campo convertido de la misma manera:
Luego, utiliza este Campo
created
al seleccionar datos de la base de datos:Esto garantizará que el
Converter
se utilice para convertir elTimestamp
a unInstant
al seleccionar datos de la base de datos.