es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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,>

Tags:  ,

Answer

  1. Avatar for 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 Campo name se crea utilizando un tipo de dato convertido (SQLDataType.TIMESTAMP.asConvertedDataType(Converter.of(MY_CONVERTER))), pero esto no se está haciendo para el Campo created.

    Para solucionar esto, puedes crear un Campo convertido de la misma manera:

    public static Field<instant> created = DSL.field(DSL.name(table.getCreated(), "created"), SQLDataType.TIMESTAMP.asConvertedDataType(Converter.of(MY_CONVERTER)));    
    

    Luego, utiliza este Campo created al seleccionar datos de la base de datos:

    public static UserDto from(Record record) {
        UserDto user = new UserDto();
        user.setName(record.get(User.name));
        user.setCreated(record.get(User.created));
        return user;
    }
    

    Esto garantizará que el Converter se utilice para convertir el Timestamp a un Instant al seleccionar datos de la base de datos.

Comments are closed.