Jdbi: El mapeador incorporado para ZonedDateTime descarta la información de la zona horaria

Creado en 21 dic. 2017  ·  43Comentarios  ·  Fuente: jdbi/jdbi

Existe un mapeador incorporado para ZonedDateTime que parece que el TIMESTAMP WITH TIME ZONE SQL es directamente compatible, pero el mapeador no lo hace.

Creo que exponer un mapeador para tipos con reconocimiento de zonas que no son conscientes de zonas no es lo correcto.

bug feature improvement

Comentario más útil

Para ser honesto, estoy de acuerdo con @findepi, donde dijo que jdbi no debería proporcionar mapeadores para cosas que en realidad no se pueden mapear con precisión, como zonas horarias / compensaciones que no persisten ... La idea de un "compromiso" aquí suena muy peligrosa para mí, siempre he considerado que la integridad total de los datos es una de las principales prioridades en cualquier proyecto. Los usuarios no deberían tener que volver a comprobar que las bibliotecas funcionan correctamente.

Prefiero descubrir con una excepción de tiempo de ejecución durante una ejecución de prueba que jdbi no proporciona un mapeador para un tipo determinado y luego escribir uno yo mismo, que averiguar quién sabe cuándo un mapeador proporcionado por jdbi se ha alterado furtivamente mis datos.

Tengo una prueba unitaria grande que escribe y luego lee valores de muchos tipos, para verificar la corrección de la implementación / integridad de los datos tanto en la propia base de datos (hsqldb) como en jdbi, por lo que podría escribir mapeadores / argumentos de jdbi para manejar cualquier problema. Tuve que escribir varios ahora porque hsqldb actualmente básicamente no tiene soporte para java.time a pesar de que la especificación lo dice (gran error). Todavía no había pensado en probar objetos java.time con zonas / compensaciones que no sean las de mi sistema, así que lo hice y, por supuesto, todos regresan con el restablecimiento de compensación / zona a los valores del sistema, pero debido al mapeo de jdbi a la marca de tiempo, no debido a errores de hsqldb.

Sugiero que esos mapeadores defectuosos se eliminen de jdbi3 y se trasladen a artefactos específicos del proveedor (jdbi3-hsqldb y otros) donde su implementación se puede corregir por completo.

Es posible que pueda contribuir con jdbi-hsqldb yo mismo, ya que de todos modos ya he escrito todos los mapeadores y argumentos necesarios para mi propio proyecto.

Todos 43 comentarios

Tiene razón, pero esto es todo lo que JDBC admite en este momento. Tenemos que convertir todos los tipos java.time a tipos java.util o java.sql que carecen de datos de zona horaria / desplazamiento.

Por curiosidad, ¿estás usando Postgres? Porque su TIMESTAMP WITH TIME ZONE se comporta de manera diferente a lo esperado.

estás usando Postgres? Porque su TIMESTAMP WITH TIME ZONE se comporta de manera diferente a lo esperado.

soy consciente. (Gran decepción por la base de datos que, por lo demás, cumple con los estándares).

Tiene razón, pero esto es todo lo que JDBC admite en este momento.

Esperaba que JDBI extrajera los org.h2.api.TimestampWithTimeZone H2 sin necesidad de que lo hiciera manualmente, de alguna manera.
Como no conozco ninguna forma "portátil" (que funcione con diferentes controladores) para extraer el valor TIMESTAMP W / TZ, no tengo ninguna solución verdadera.
Sin embargo, si no extrae toda la información, no debe fingir que lo hace, es decir, en mi opinión, no debe haber un mapeador integrado para ZonedDateTime . De lo contrario, lo estás haciendo como Postgres, no como yo esperaba.

Creo que sigue siendo conveniente si un usuario quiere usar ZonedDateTime y no le importa que se devuelva en la zona horaria del servidor de aplicaciones en lugar de la zona horaria de la base de datos.

Por cierto, Dropwizard usa una versión diferente del mapeador para JDBI2, donde un usuario puede establecer explícitamente la zona horaria de la base de datos: https://github.com/dropwizard/dropwizard/blob/master/dropwizard-jdbi/src/main/java /io/dropwizard/jdbi/args/ZonedDateTimeMapper.java

Si pudiera proporcionar un código de ejemplo sobre cómo obtener / configurar ZonedDateTime con H2, me complacería agregarlo al complemento.

Creo que sigue siendo conveniente si un usuario quiere usar ZonedDateTime y no le importa que se devuelva en la zona horaria del servidor de aplicaciones en lugar de la zona horaria de la base de datos.

@arteam , si el usuario es consciente de hacer esta elección, estoy de acuerdo.

Sin embargo, AFAIR https://github.com/jdbi/jdbi/blob/master/core/src/main/java/org/jdbi/v3/core/mapper/BuiltInMapperFactory.java#L182 ni siquiera funcionará en H2 para TS w TZ, ya que rs.getTimestamp(..) no es compatible con ese tipo.

Si pudiera proporcionar un código de ejemplo sobre cómo obtener / configurar ZonedDateTime con H2, me complacería agregarlo al complemento.

No conozco ninguna forma portátil, la única forma que conozco es (org.h2.api.TimestampWithTimeZone) rs.getObject(..) y, por ejemplo, Oracle sería similar, pero con una clase específica de Oracle.

En general, prefiero que la API _forzado_ use la transformación correcta (marca de tiempo en LocalDateTime ) y agregue "zone-ing" explícitamente.

Parece que no estás de acuerdo, lo que significa que no tiene sentido mantener abierto este asunto.

Una cosa que hacemos en nuestra pila, en realidad afirmamos que la zona horaria de Java == la zona horaria de Postgres, en cuyo caso todo funciona a la perfección. ¿Deberíamos emitir una advertencia si hay una discrepancia? ¿Sería un buen compromiso entre habilitar las funciones que la gente espera y ser TZ-correcto?

No estoy seguro de por qué cerró esto tan rápido, sentí que había más de qué hablar.

Incluso si no podemos resolver esto de forma genérica para todos los proveedores, definitivamente podemos respaldar esto por proveedor.

Los mapeadores y las fábricas de argumentos que se envían con Jdbi pueden anularse simplemente registrando otro mapeador / argumento. El último registrado (por tipo) gana.

Si observa la fuente de PostgresPlugin , verá que registra JavaTimeMapperFactory que proporciona mapeadores alternativos usando ResultSet.getObject(Class) por LocalDate , LocalTime , LocalDateTime y OffsetDateTime , que son directamente compatibles con el controlador JDBC de Postgres.

Si H2 tiene una forma de almacenar ZonedDateTime sin eliminar la zona, podemos modificar H2DatabasePlugin para usar un mapeador personalizado para eso.

Volveré a abrir esto por ahora, hay una buena discusión aquí, y @findepi ¡ nos preocupamos mucho por hacer las cosas correctamente! También somos pragmáticos y la gente espera poder utilizar los tipos de tiempo ...

¿Entiendo correctamente de esta conversación que el equipo de jdbi estaría interesado en tener, por ejemplo, un subproyecto / artefacto / ... jdbi3-hsqldb que proporciona argumentos y mapeadores específicamente para hsqldb (que admite el uso de objetos java.time directamente a través de setObject / getObject sin conversión)?

Absolutamente.

Para ser honesto, estoy de acuerdo con @findepi, donde dijo que jdbi no debería proporcionar mapeadores para cosas que en realidad no se pueden mapear con precisión, como zonas horarias / compensaciones que no persisten ... La idea de un "compromiso" aquí suena muy peligrosa para mí, siempre he considerado que la integridad total de los datos es una de las principales prioridades en cualquier proyecto. Los usuarios no deberían tener que volver a comprobar que las bibliotecas funcionan correctamente.

Prefiero descubrir con una excepción de tiempo de ejecución durante una ejecución de prueba que jdbi no proporciona un mapeador para un tipo determinado y luego escribir uno yo mismo, que averiguar quién sabe cuándo un mapeador proporcionado por jdbi se ha alterado furtivamente mis datos.

Tengo una prueba unitaria grande que escribe y luego lee valores de muchos tipos, para verificar la corrección de la implementación / integridad de los datos tanto en la propia base de datos (hsqldb) como en jdbi, por lo que podría escribir mapeadores / argumentos de jdbi para manejar cualquier problema. Tuve que escribir varios ahora porque hsqldb actualmente básicamente no tiene soporte para java.time a pesar de que la especificación lo dice (gran error). Todavía no había pensado en probar objetos java.time con zonas / compensaciones que no sean las de mi sistema, así que lo hice y, por supuesto, todos regresan con el restablecimiento de compensación / zona a los valores del sistema, pero debido al mapeo de jdbi a la marca de tiempo, no debido a errores de hsqldb.

Sugiero que esos mapeadores defectuosos se eliminen de jdbi3 y se trasladen a artefactos específicos del proveedor (jdbi3-hsqldb y otros) donde su implementación se puede corregir por completo.

Es posible que pueda contribuir con jdbi-hsqldb yo mismo, ya que de todos modos ya he escrito todos los mapeadores y argumentos necesarios para mi propio proyecto.

Estoy de acuerdo en que probablemente hubiera sido el camino más sabio, sin embargo, en este punto se lanza v3 y el gato está fuera de la bolsa.

Eliminar estos mapeadores o fábricas de argumentos sería un cambio radical para cualquier usuario existente que dependa de ellos.

Si alguien ya depende de ellos (consciente de sus fallas o no), creo que sería bastante simple para esos usuarios volver a parchearlos: las conversiones son bastante simples. Mantenerlos, por otro lado, conducirá a que cada vez más personas como yo asuman que funciona porque se proporciona (honestamente, ¿quién conoce todas las especificaciones técnicas como la no compatibilidad de zonas horarias de jdbc de memoria?) Y puede que no descubrir más tarde que sus datos estaban siendo mal manejados ...
Básicamente, creo que el daño futuro potencial al permitirles quedarse es mucho mayor que el daño causado ahora a los pocos que se han actualizado eliminándolos.

@TheRealMarnes Creo que eliminar una característica (incluso una vez que estemos de acuerdo en que no debería existir) no es tan simple. La gente tiende a asumir el control de versiones semántico (independientemente de si el proyecto lo sigue o no). No conozco las reglas del proyecto, pero por lo general lo desaprobaría en v3 (aquí la desaprobación es complicada, porque no hay un método de API que pueda marcarse como obsoleto, la documentación y el registro es lo que queda) y eliminar la función en v4 , esperando que la gente lea las notas de la versión o la guía de migración.

Estoy de acuerdo en que algo así nunca es simple y las soluciones siempre harán infeliz a alguien, pero tiendo a pensar que el fin justifica los medios y alterar un sistema defectuoso para reemplazarlo por uno mejor a largo plazo siempre vale la pena. Y no creo que sea irrazonable esperar que la gente lea las notas de la versión o la guía de migración ... Con mantenimiento y actualizaciones menores, claro, pero no con una actualización importante. Jdbi3 en sí mismo es inutilizable viniendo de jdbi2 sin leer también la nueva guía.

Creo que podría respaldar una solución para deshabilitar esos mapeadores / argumentos, siempre que reinstalarlos fuera una línea simple, ¿tal vez mover esos mapeadores a un complemento?

¿Como un jdbi3-core-experimental no específico del proveedor?
Editar: mi mal, te refieres a jdbi.installPlugin(new ExperimentalMappersPlugin())

Esa sería la idea, aunque estos no son realmente "experimentales" como tales.

TimezoneInsensitiveJavaTimeMappers luego: P

No son solo los mapeadores, también son las fábricas de argumentos.

¿Qué tal JavaTimeYoloTZPlugin : guiño:

Incluso si no podemos resolver esto de forma genérica para todos los proveedores, definitivamente podemos respaldar esto por proveedor.

@qualidafial Me enteré recientemente de que parece haber un estándar de facto emergente para recuperar valores de fecha / hora en el mundo posterior a Java8.

Primero, un poco más de antecedentes:

  • Creé este problema sobre la conversión TIMESTAMP WITH TIME ZONE JDBI a ZonedDateTime , que descarta la información de la zona horaria
  • hay otro problema con todas las API de JDBC. Así es como se supone que se recuperan los objetos TIMESTAMP , DATE , TIME , es decir, utilizando clases java.sql.{Timestamp,Date,Time} . Todas las clases se extienden desde java.util.Date . Alguien recuerda cómo Calendar se introdujo y java.util.Date 's métodos que tratan de año / mes / día / hora / minuto / segundo en desuso? Por una buena razón (y no me refiero a que Calendar resolvió todos los problemas).

    • no puede recuperar java.sql.Timestamp de una base de datos, si su _ zona horaria de JVM_ no respetó esa hora local. Entonces, una aplicación que se ejecuta en EE. UU. Puede almacenar un valor de marca de tiempo de 2017-03-26 02:30:00 (¡sin zona!) En alguna base de datos compartida, pero una aplicación que se ejecuta en Europa (con, por ejemplo, Europe/Berlin como zona JVM) no lo hará. poder recuperar esta marca de tiempo, porque había horario de verano en Europa en ese momento.

    • oh, lo mismo se aplica a java.sql.Date , porque esta es una clase casi idéntica. java.sql.Date representa la fecha como si fuera java.sql.Timestamp a la medianoche, pero a veces no hay medianoche. Hay zonas con cambios de horario de verano a medianoche (ya sea actual o en el pasado).

    • ¿Crees que java.sql.Time está libre de este problema, porque representa la hora recuperada como una marca de tiempo en 1970-01-01? Desafortunadamente no, ya que hay zonas que fueron lo suficientemente agradables como para tener un cambio de política en esa fecha (por ejemplo, America/Bahia_Banderas , America/Hermosillo ). Si JVM es una de estas zonas, un programa que utilice JDBC no podrá recuperar ciertos valores TIME .

Una no solución sería recuperar usando la API antigua de JDBC y convertirlas en nuevas clases. Pero esto es generalmente incorrecto:

  • ~ resultSet.getTimestamp(col).toLocalDateTime() ~
  • ~ resultSet.getDate(col).toLocalDate() ~
  • ~ resultSet.getTime(col).toLocalTime() ~

Esto se compila y funciona bien, excepto que no resuelve ninguno de los problemas descritos anteriormente (incluso la recuperación de la fecha no funciona, si la zona JVM es Pacific/Apia y la fecha de recuperación es 2011-12-30 ;)

Ahora, a la solución emergente. ResultSet tiene esta API menos popular que le permite pedirle al controlador JDBC que convierta el tipo por usted:

  • resultSet.getObject(col, LocalDateTime.class) // for TIMESTAMP
  • resultSet.getObject(col, LocalDate.class) // for DATE
  • resultSet.getObject(col, LocalTime.class) // for TIME
  • resultSet.getObject(col, ZonedDateTime.class) // for TIMESTAMP WITH TIME ZONE

Esto parece funcionar con controladores JDBC para PostgreSQL, MySQL, Oracle y H2. Y, por arte de magia, evita los problemas de "irrepresentabilidad en la zona JVM" descritos anteriormente.
A pesar de que esta conversión aún no está implementada, por ejemplo, en el controlador de SQL Server, creo que esto podría hacerse _el_ mapeo predeterminado para las clases de Java Time que envía JDBI.

Nota:
La especificación JDBC 4.2 no exige que un controlador deba implementar esto. Sin embargo, la especificación requiere que PreparedStatement.setObject y RowSet.setObject acepten instancias de las clases Java Time y las traten correctamente, por lo que los controladores deben admitir estas clases explícitamente de todos modos.

¡Eso es genial! Mi principal preocupación es que el cambio a este enfoque podría manifestarse como una regresión para los usuarios que utilizan controladores esotéricos. Pero tal vez con el mensaje apropiado en las notas de la versión podríamos hacer este pequeño cambio técnicamente importante en nombre de hacer las cosas de la manera correcta ...

@stevenschlansker tienes razón. Creo que JDBI podría proporcionar

  • conjunto opcional de asignaciones que un usuario puede conectar para restaurar el comportamiento original
  • algún comentario apropiado en las notas de la versión (o incluso un aumento de la versión principal)

Mantengámoslo en una versión menor, acabamos de lanzar 3, y este es solo un cambio importante si lo mantiene mal ...;)

Solo para reproducir lo que parece que estoy escuchando:

  • Mueva los mapeadores java.time incorporados existentes a un complemento separado (me gusta YoloTimePlugin )
  • Agregue nuevos mapeadores integrados en su lugar que usen ResultSet.getObject(column, type) lugar de convertir de tipos java.sql.
  • Documente la mierda de este cambio radical en las notas de la versión: explique el impacto de este cambio y qué proveedores de bases de datos se verán afectados y qué deben hacer los usuarios para mitigar los problemas.

Puedo respaldar esto.

Sin embargo, todavía no hemos respondido a la pregunta sobre la vinculación de estos objetos de fecha / hora. Cualquier cosa que cambiemos acerca de los resultados del mapeo _fuera_ de la base de datos debe reflejarse en la forma en que enlazamos los argumentos de fecha / hora _en_ ​​declaraciones SQL.

Todo lo que cambiemos sobre los resultados de mapeo de la base de datos debe reflejarse en la forma en que vinculamos los argumentos de fecha / hora en las declaraciones SQL.
@qualidafial , muy buena pregunta. No he estado probando esto. Esto está explícitamente cubierto por la especificación JDBC 4.2, por lo que _should just work ™ _.

Esto está explícitamente cubierto por la especificación JDBC 4.2, por lo que _should just work ™ _.

Esto supone que los implementadores de controladores JDBC siguen las especificaciones a la perfección. Todavía tengo que encontrar una implementación de controlador JDBC sin errores.

Tengo la sensación de que sería demasiado engorroso proporcionar complementos con mapeadores para cada base de datos e incluso sus diferentes versiones que tienen diferentes soportes para tipos de datos. Tal vez un enfoque de pizarra en blanco podría funcionar: comienza con una instancia de Jdbi sin mapeadores preinstalados, y el artefacto principal proporciona un montón de mapeadores diferentes que puede elegir para instalar manualmente, algunos con una lógica diferente para manejar los mismos tipos de datos: obtener / setObject, get / setX, conversión a otro tipo, etc. Debería averiguar por sí mismo qué mapeadores son los mejores para su base de datos (versión) y lógica de aplicación, y usar pruebas unitarias para mantenerlo bajo control.

Eso es básicamente lo que ya estoy haciendo ahora en mi proyecto. Hay algunos mapeadores preinstalados en Jdbi que no funcionan con mi base de datos y no los necesito por ahora, así que los he anulado con fábricas de argumentos / mapeadores que arrojan una UnsupportedOperationException, y otros los he anulado con mejor implementaciones (ver más abajo).

Esta sería una solución para aquellos a quienes les gusta tener intimidad con su base de datos para asegurarse de que todo funcione absolutamente, y no cambiaría nada para las personas que quieren cosas para Just Werk ™ (en la medida en que realmente lo hace):

  • agregue un método a las instancias de Jdbi para borrar todos sus mapeadores / argumentos (pizarra limpia)
  • exponer el mapeador / arg incorporado actual para que lo instalemos manualmente
  • siga agregando implicaciones de mapeador alternativo al artefacto principal cuando aumente la demanda y deje que las personas las instalen por su cuenta, generando lo que sea posible como a continuación

Al hacer esto, me las arreglé para encontrar ... demasiados puntos en el controlador hsqldb donde se desvían de sus propias especificaciones (informadas y corregidas en la fuente, todavía esperando que finalmente publiquen un artefacto actualizado), y funcionó alrededor de esas imperfecciones encontrando yo mismo la lógica del mapeo de trabajo.

// I want strings handled differently
<strong i="13">@Component</strong>
public class CleanStringArgumentFactory extends AbstractArgumentFactory<String> {
    protected CleanStringArgumentFactory() {
        super(Types.VARCHAR);
    }

    <strong i="14">@Override</strong>
    protected Argument build(String value, ConfigRegistry config) {
        return (position, statement, ctx) -> statement.setString(position, StringUtils.trimToNull(value));
    }
}
// no need for jdbi's built-in logic
<strong i="17">@Component</strong>
public class SetObjectArgumentFactory implements ArgumentFactory {
    private static final Set<Type> SUPPORTED = ImmutableSet.of(UUID.class, LocalDateTime.class);

    <strong i="18">@Override</strong>
    public Optional<Argument> build(Type type, Object value, ConfigRegistry config) {
        return SUPPORTED.contains(type)
            ? Optional.of(new LoggableArgument(value, (position, statement, context) -> statement.setObject(position, value)))
            : Optional.empty();
    }
}
// these built-ins don't work and I don't need them anyway
<strong i="21">@Component</strong>
public class UnsupportedArgumentFactory implements ArgumentFactory {
    private static final Set<Type> UNSUPPORTED = ImmutableSet.of(ZonedDateTime.class, OffsetDateTime.class, OffsetTime.class);

    <strong i="22">@Override</strong>
    public Optional<Argument> build(Type type, Object value, ConfigRegistry config) {
        if (UNSUPPORTED.contains(type)) {
            throw new UnsupportedOperationException(type.getTypeName() + " is not supported at the moment");
        } else {
            return Optional.empty();
        }
    }
}
// voodoo
<strong i="25">@Inject</strong>
    public JdbiConfiguration(
        @Named("dataSource") DataSource dataSource,
        Set<ArgumentFactory> arguments,
        Set<ColumnMapper> mappers,
        Set<ColumnMapperFactory> mapperFactories
    ) {
        jdbi = Jdbi.create(dataSource);
        jdbi.clearMappings();

        jdbi.installPlugin(new SqlObjectPlugin());

        arguments.forEach(jdbi::registerArgument);
        mapperFactories.forEach(jdbi::registerColumnMapper);
        mappers.forEach(jdbi::registerColumnMapper);

        // ...

        // Jdbi instance fine-tuned for my exact database and demands, without surprises and at my own responsibility

Howbouda? Por ejemplo, podría proporcionar un SetObjectArgumentFactory que debe inicializarse con un conjunto de clases en las que debería activarse y todo tipo de variaciones de la lógica de mapeo para muchos tipos de datos, con algún comportamiento configurable cuando corresponda. Todo el mundo está feliz. Requiere algo de trabajo por parte del usuario final, pero me siento bien sabiendo que jdbi hace exactamente lo que quiero que haga y lo que mi base de datos admite.

Tengo la sensación de que sería demasiado engorroso proporcionar complementos con mapeadores para cada base de datos e incluso sus diferentes versiones que tienen diferentes soportes para tipos de datos.

Me encantaría tener complementos para muchos proveedores de bases de datos. Venga uno, venga todos: si su base de datos necesita / quiere algunas personalizaciones para adaptar Jdbi a las idiosincrasias del proveedor de la base de datos o su controlador JDBC, queremos saberlo. O mejor aún, ¡queremos solicitudes de extracción! :)

Puntos de bonificación si su base de datos es compatible directamente con TravisCI para que podamos ejecutar pruebas en ella: https://docs.travis-ci.com/user/database-setup/

En cuanto a su sugerencia de "pizarra en blanco", solo tengo objeciones menores:

  • Probablemente pondría el método clearMappings() directamente en las clases RowMappers , ColumnMappers , Arguments y JdbiCollectors config en lugar de en Jdbi , y los llamaría clear() .
  • Dudo un poco en hacer públicos los mapeadores, argumentos y coleccionistas integrados. Algunos de ellos tienen nombres o diseños extravagantes que nos salimos con la nuestra porque son internos. Probablemente me gustaría refactorizarlos antes de convertirlos en parte de la API.
  • Me pregunto si la pizarra en blanco es realmente necesaria. Todas las clases de registro de Jdbi utilizan el enfoque de últimos triunfos registrados, por lo que siempre es posible anular el comportamiento listo para usar. En ese sentido, la pizarra en blanco se siente un poco exagerada.

@ jdbi / contributors ¿Alguien más quiere opinar?

Incluí la idea de la pizarra en blanco para evitar usar accidentalmente un mapeador predeterminado en caso de que olvidara registrar uno de su elección. Prefiero tener una NotImplementedException que una impl predeterminada. Las últimas victorias son buenas y todo, pero no hay forma de saber cuáles debes anular en caso de que no quieras ninguna.

No es que duela tenerlo. Si las personas no quieren ese enfoque, no necesitan llamar a los métodos claros y nada cambia para ellos. Es solo para aquellos que prefieren una forma de trabajar sin incumplimiento.

Estoy de acuerdo en que no deberíamos simplemente hacer públicos los mapeadores existentes. Si optamos por ofrecer una opción de borrón y cuenta nueva, deberíamos agrupar los mapeadores y carpetas en Plugin fragmentos razonables, PrimitivesPlugin , BoxedPrimitivesPlugin , CollectionsPlugin , lo que sea.

Luego, podemos agregar una nueva fábrica para el jdbi "base" sin ninguna configuración, y modificar las fábricas existentes para usar esto y agregar WholeJdbiEnchiladaPlugin .

Estoy algo en contra de 'clear' a menos que podamos mostrar casos en los que es difícil construirlo de forma aditiva; me parece un olor a código.

Estoy algo en contra de 'clear' a menos que podamos mostrar casos en los que es difícil construirlo de forma aditiva; me parece un olor a código.

Bueno, si agrega una fábrica jdbi sin preconfiguración separada, entonces no será difícil construirla de forma aditiva, por lo que no necesitaremos ningún clear () de hecho.

Bien, creo que estamos de acuerdo aquí, solo estaba expresando una preferencia por agregar un nuevo método de fábrica "limpio" sobre un estilo clear() .

Entonces, ¿esto resuelve los problemas de todos? Personalmente, creo que el plan suena bastante sexy.

  • hacer Jdbi sin valores predeterminados (arroja excepciones en casi todo)
  • hacer que todos los mapeadores y carpetas existentes (y controladores de tx, etc.) sean conectables ( PrimitivesPlugin , BoxedPrimitivesPlugin , etc.), como paquetes de complementos y como clases individuales
  • proporcionar algunas implementaciones alternativas ( UTCJavaTimePlugin vs LocalJavaTimePlugin vs ConvertJavaTimeToUtilDatePlugin , GetObjectMapper.forClasses(Class... cs) , SetObjectArgumentFactory.forClasses(Class... cs) , NullsToDefaultsPrimitivesPlugin vs NullThrowsExceptionPrimitivesPlugin ) y exponerlos de la misma manera (en complementos e individualmente), para que las personas puedan componer su propia lógica de mapeo total deseada, tomando solo exactamente lo que quieren. Potencialmente, se necesita mucha configuración de mapeador aquí, como diferentes estrategias para manejar nulos ilegales o zonas horarias faltantes, y otras posibles disparidades
  • tal vez hacer complementos de paquete específicos de db, por lo que los usuarios con bases de datos populares + versiones pueden comenzar desde un Jdbi sin configuración e instalar esquemas de mapeo buenos conocidos de una línea para su db ( HsqlDb2_4_0Plugin ), nuevamente con opciones de configuración para diferentes estrategias
  • y hacerlo todo compatible con versiones anteriores simplemente haciendo que los métodos de fábrica actuales realicen la preconfiguración que tenemos ahora ( BuiltInGenericPreconfigurationPlugin ), junto con los métodos de fábrica sin configuración.

hacer Jdbi sin valores predeterminados

No tengo una opinión muy fuerte, pero todo esto suena muy complejo desde la perspectiva del usuario. Los usuarios deberán comprender varias asignaciones posibles para los tipos que desean usar y elegir una adecuada. Esto es difícil, especialmente cuando los temporales están en juego; realmente no es trivial comprender las diferentes opciones posibles.

Los usuarios deberán comprender varias asignaciones posibles para los tipos que desean usar y elegir una adecuada.

No, solo si quieren. Los métodos de fábrica existentes seguirán generando instancias Jdbi con exactamente los mismos mapeadores preinstalados que tienen ahora. También obtendremos métodos de fábrica de configuración de bricolaje, y las personas que opten por ellos deberán descubrir la intimidad del mapeo. También habrá un punto intermedio, donde obtendrá una instancia de bricolaje y simplemente instalará YourDbAndVersionPlugin y continuará con lo que sea que haga. Mi extensa explicación fue principalmente aspectos internos de jdbi y uso avanzado, no la línea de base.

TLDR: aún podrá hacer Jdbi.create(dataSource) y no tendrá que dar ningún grito adicional al respecto que no le haya dado. Alguien más simplemente elegirá Jdbi.createBlank(dataSource).install(x).install(y).install(z)...

Estoy a bordo, excepto que no creo que debamos desaprobar las fábricas existentes, creo que la mayoría de los usuarios continuarán usándolo ya que el comportamiento "listo para usar" es bastante bueno.

Lo suficientemente justo

@TheRealMarnes Toda esta conversación comenzó tratando con tipos de datos JSR-310 que no son compatibles directamente con JDBC.

Creo que hay consenso sobre eliminar los mapeadores y argumentos de java.time errantes y ponerlos en un complemento en lugar de incorporarlos.

¿Todavía quieres seguir con eso?

¿Solo los de java.time? ¿Un JavaTimePlugin?

Sí, un complemento solo para los tipos java.time, pero con un nombre para comunicar que los argumentos y los mapeadores son implementaciones ingenuas y con pérdidas como lo describió

SimplisticJavaTimePlugin ?

Esperar con esto hasta que se ocupen de mis otros RP ... Es demasiado al mismo tiempo.

¿Fue útil esta página
0 / 5 - 0 calificaciones