Jdbi: O mapeador integrado para ZonedDateTime descarta informações de fuso horário

Criado em 21 dez. 2017  ·  43Comentários  ·  Fonte: jdbi/jdbi

Existe um mapeador embutido para ZonedDateTime que parece que TIMESTAMP WITH TIME ZONE do SQL é diretamente suportado, mas o mapeador não faz isso.

Acho que expor um mapeador para tipo com reconhecimento de zona não é a coisa certa a fazer.

bug feature improvement

Comentários muito úteis

Para ser honesto, eu concordo com @findepi, onde ele disse que o jdbi não deve fornecer mapeadores para coisas que realmente não podem ser mapeadas com precisão, como fusos horários / deslocamentos que não são persistentes ... A ideia de um "compromisso" aqui parece muito perigosa para mim - sempre considerei a integridade total dos dados uma das maiores prioridades em qualquer projeto. Os usuários não precisam verificar novamente se as bibliotecas estão funcionando corretamente.

Prefiro descobrir com uma exceção de tempo de execução durante uma execução de teste que jdbi não fornece um mapeador para um determinado tipo e, em seguida, escrever um eu mesmo, do que descobrir quem sabe quando que um mapeador fornecido por jdbi foi furtivamente alterado meus dados.

Eu tenho um grande teste de unidade que grava e lê valores de muitos tipos, para verificar a correção da implementação / integridade dos dados no próprio banco de dados (hsqldb) e jdbi, para que eu possa escrever mapeadores / argumentos jdbi para lidar com quaisquer problemas. Tive que escrever vários agora porque hsqldb atualmente basicamente não tem suporte para java.time, apesar da especificação dizendo isso (bug enorme). Eu não tinha pensado em testar objetos java.time com zonas / deslocamentos diferentes do meu sistema ainda, então eu apenas fiz, e com certeza, todos eles voltaram com o deslocamento / redefinição da zona para os valores do sistema, mas devido ao mapeamento do jdbi para carimbo de data / hora, não por causa de bugs do hsqldb.

Sugiro que esses mapeadores defeituosos sejam removidos do jdbi3 e movidos para artefatos específicos do fornecedor (jdbi3-hsqldb e outros), onde sua implementação pode ser totalmente correta.

Eu posso contribuir com jdbi-hsqldb sozinho, uma vez que já escrevi todos os mapeadores e argumentos necessários para meu próprio projeto.

Todos 43 comentários

Você está correto, mas isso é tudo que o JDBC suporta no momento. Temos que converter todos os tipos java.time para tipos java.util ou java.sql que não possuem dados de fuso horário / deslocamento.

Por curiosidade, você está usando o Postgres? Porque seu TIMESTAMP WITH TIME ZONE se comporta de maneira diferente do que você esperava.

você está usando o Postgres? Porque seu TIMESTAMP WITH TIME ZONE se comporta de maneira diferente do que você esperava.

Eu estou ciente. (Grande decepção para um banco de dados em conformidade com os padrões, aliás.)

Você está correto, mas isso é tudo que o JDBC suporta no momento.

Eu esperava que o JDBI puxasse org.h2.api.TimestampWithTimeZone H2 sem precisar que eu fizesse isso manualmente, _de alguma forma_.
Como não conheço nenhuma maneira "portátil" (trabalhando em diferentes drivers) de obter o valor TIMESTAMP W / TZ, não tenho nenhuma solução verdadeira.
No entanto, se você não puxar todas as informações, você não deve fingir que o faz - isto é, IMO, não deve haver nenhum mapeador embutido para ZonedDateTime . Caso contrário, você está fazendo exatamente como Postgres - não o que eu esperava.

Eu acho que ainda é conveniente se um usuário deseja usar ZonedDateTime e não se importa se ele é retornado no fuso horário do servidor de aplicativos em vez do fuso horário do banco de dados.

A propósito, o Dropwizard usa uma versão diferente do mapeador para JDBI2, onde um usuário pode definir explicitamente o fuso horário do banco de dados: https://github.com/dropwizard/dropwizard/blob/master/dropwizard-jdbi/src/main/java /io/dropwizard/jdbi/args/ZonedDateTimeMapper.java

Se você pudesse fornecer um código de exemplo para obter / definir ZonedDateTime com H2, ficaria feliz em adicioná-lo ao plug-in.

Acho que ainda é conveniente se um usuário deseja usar ZonedDateTime e não se importa se ele é retornado no fuso horário do servidor de aplicativos em vez do fuso horário do banco de dados.

@arteam , se o usuário estiver ciente de fazer essa escolha - eu concordo.

No entanto, AFAIR https://github.com/jdbi/jdbi/blob/master/core/src/main/java/org/jdbi/v3/core/mapper/BuiltInMapperFactory.java#L182 nem mesmo funcionará em H2 para TS w TZ, já que rs.getTimestamp(..) não é compatível com esse tipo.

Se você pudesse fornecer um exemplo de código para obter / definir ZonedDateTime com H2, ficaria feliz em adicioná-lo ao plug-in.

Não conheço nenhuma forma portátil - a única forma que conheço é (org.h2.api.TimestampWithTimeZone) rs.getObject(..) e, por exemplo, Oracle seria semelhante, mas com classe específica de Oracle.

Geralmente, eu prefiro ser _forçado_ pela API para usar a transformação correta (carimbo de data / hora para LocalDateTime ) e adicionar "zoneamento" explicitamente.

Você parece discordar, o que significa que não adianta manter esse assunto em aberto.

Uma coisa que fazemos em nossa pilha, na verdade, afirmamos que fuso horário do Java == fuso horário do Postgres, caso em que tudo funciona perfeitamente. Devemos talvez emitir um aviso se houver uma incompatibilidade? Isso seria um bom meio-termo entre habilitar os recursos que as pessoas esperam e ser correto para o TZ?

Não tenho certeza por que você fechou isso tão rapidamente, senti que havia mais para discutir.

Mesmo que não possamos resolver isso genericamente para todos os fornecedores, podemos definitivamente oferecer suporte para cada fornecedor.

Os mapeadores e fábricas de argumento que vêm com Jdbi podem ser substituídos simplesmente registrando outro mapeador / argumento. Últimos ganhos registrados (por tipo).

Se você olhar a fonte de PostgresPlugin , verá que ela registra JavaTimeMapperFactory que fornece mapeadores alternativos usando ResultSet.getObject(Class) para LocalDate , LocalTime , LocalDateTime e OffsetDateTime , que são diretamente suportados pelo driver Postgres JDBC.

Se H2 tem uma maneira de armazenar ZonedDateTime sem eliminar a zona, podemos modificar H2DatabasePlugin para usar um mapeador personalizado para isso.

Vou reabrir isso por agora, há uma boa discussão aqui, e @findepi, nós nos preocupamos muito em fazer as coisas corretamente! Também somos pragmáticos e as pessoas esperam poder usar os tipos de tempo ...

Eu entendi corretamente a partir desta convenção que a equipe jdbi estaria interessada em ter, por exemplo, um subprojeto / artefato / jdbi3-hsqldb ... que fornece argumentos e mapeadores especificamente para hsqldb (que suporta o uso de objetos java.time diretamente por meio de setObject / getObject sem conversão)?

Absolutamente.

Para ser honesto, eu concordo com @findepi, onde ele disse que o jdbi não deve fornecer mapeadores para coisas que realmente não podem ser mapeadas com precisão, como fusos horários / deslocamentos que não são persistentes ... A ideia de um "compromisso" aqui parece muito perigosa para mim - sempre considerei a integridade total dos dados uma das maiores prioridades em qualquer projeto. Os usuários não precisam verificar novamente se as bibliotecas estão funcionando corretamente.

Prefiro descobrir com uma exceção de tempo de execução durante uma execução de teste que jdbi não fornece um mapeador para um determinado tipo e, em seguida, escrever um eu mesmo, do que descobrir quem sabe quando que um mapeador fornecido por jdbi foi furtivamente alterado meus dados.

Eu tenho um grande teste de unidade que grava e lê valores de muitos tipos, para verificar a correção da implementação / integridade dos dados no próprio banco de dados (hsqldb) e jdbi, para que eu possa escrever mapeadores / argumentos jdbi para lidar com quaisquer problemas. Tive que escrever vários agora porque hsqldb atualmente basicamente não tem suporte para java.time, apesar da especificação dizendo isso (bug enorme). Eu não tinha pensado em testar objetos java.time com zonas / deslocamentos diferentes do meu sistema ainda, então eu apenas fiz, e com certeza, todos eles voltaram com o deslocamento / redefinição da zona para os valores do sistema, mas devido ao mapeamento do jdbi para carimbo de data / hora, não por causa de bugs do hsqldb.

Sugiro que esses mapeadores defeituosos sejam removidos do jdbi3 e movidos para artefatos específicos do fornecedor (jdbi3-hsqldb e outros), onde sua implementação pode ser totalmente correta.

Eu posso contribuir com jdbi-hsqldb sozinho, uma vez que já escrevi todos os mapeadores e argumentos necessários para meu próprio projeto.

Eu concordo que provavelmente teria sido o caminho mais sábio, no entanto, neste ponto a v3 foi lançada e o gato está fora da bolsa.

Remover esses mapeadores ou fábricas de argumento seria uma mudança significativa para qualquer usuário existente que dependa deles.

Se alguém já depende deles (ciente de suas falhas ou não), eu acho que seria simples o suficiente para esses usuários remendá-los de volta: as conversões são basicamente de uma linha. Mantê-los por outro lado levará cada vez mais pessoas como eu, que presumem que funciona porque é fornecido (honestamente, quem conhece todas as especificações técnicas, como o não suporte de fusos horários do jdbc de cor?) E podem ou não descobrir mais tarde que seus dados estavam sendo maltratados ...
Basicamente, acho que o dano potencial futuro ao permitir que eles permaneçam é muito maior do que o dano causado agora aos poucos que os atualizaram ao removê-los.

@TheRealMarnes acho que remover um recurso (mesmo quando concordamos que não deveria existir) não é tão simples. As pessoas tendem a assumir um controle de versão semântico (independentemente de o projeto segui-lo ou não). Eu não sei as regras do projeto, mas normalmente você iria no máximo descontinuá-lo na v3 (aqui a descontinuação é complicada, porque não há método de API que pode ser marcado como reprovado, documentação e registro são o que resta) e remover o recurso na v4 , esperando que as pessoas leiam as notas de versão / guia de migração.

Eu concordo que algo assim nunca é simples e as soluções sempre farão alguém infeliz, mas eu tendo a pensar que o fim justifica os meios e perturbar um sistema falho para substituí-lo por um melhor sempre vale a pena a longo prazo o transtorno. E eu não acho que esperar que as pessoas leiam as notas de lançamento / guia de migração seja irracional ... Com manutenção e pequenas atualizações, claro, mas não com uma grande atualização. O próprio Jdbi3 é inutilizável vindo do jdbi2 sem ler o novo guia também.

Acho que poderia encontrar uma solução para desabilitar esses mapeadores / argumentos, desde que reinstaurá-los fosse de uma linha - talvez mover esses mapeadores para um plug-in?

Como um jdbi3-core-experimental não específico de um fornecedor?
Editar: meu mal, você quer dizer jdbi.installPlugin(new ExperimentalMappersPlugin())

Essa seria a ideia, embora estes não sejam realmente "experimentais" como tal.

TimezoneInsensitiveJavaTimeMappers então: P

Não são apenas os mapeadores, são também as fábricas de argumentos.

Que tal JavaTimeYoloTZPlugin : wink:

Mesmo que não possamos resolver isso genericamente para todos os fornecedores, podemos definitivamente oferecer suporte para cada fornecedor.

@qualidafial aprendi recentemente que parece haver um padrão emergente de fato para recuperar valores de data / hora no mundo pós-Java8.

Primeiro, um pouco mais de fundo:

  • Eu criei este problema sobre a conversão de TIMESTAMP WITH TIME ZONE do JDBI em ZonedDateTime , que descarta informações de fuso horário
  • há outro problema, com toda a API JDBC. É assim que TIMESTAMP , DATE , TIME objetos devem ser recuperados, ou seja, usando java.sql.{Timestamp,Date,Time} classes. Todas as classes se estendem de java.util.Date . Alguém se lembra de como Calendar foi introduzido e os métodos de java.util.Date que lidam com ano / mês / dia / hora / minuto / segundo foram descontinuados? Por uma boa razão (e não quero dizer que Calendar resolveu todos os problemas).

    • você não pode recuperar java.sql.Timestamp de um banco de dados, se o seu fuso horário _JVM_ não observar esse horário local. Portanto, um aplicativo em execução nos EUA pode armazenar um valor de carimbo de data / hora de 2017-03-26 02:30:00 (sem zona!) Em algum banco de dados compartilhado, mas um aplicativo em execução na Europa (por exemplo, Europe/Berlin como zona JVM) não ser capaz de recuperar este carimbo de data / hora, porque havia horário de verão na Europa naquela época.

    • oh, o mesmo se aplica a java.sql.Date , porque esta é uma classe quase idêntica. java.sql.Date representa a data como se fosse java.sql.Timestamp à meia-noite, mas às vezes não há meia-noite. Existem zonas com mudanças de horário de verão à meia-noite (atual ou no passado).

    • você pensaria que java.sql.Time está livre desse problema, porque representa o tempo recuperado como um carimbo de data / hora em 01/01/1970? Infelizmente não, já que há zonas que foram legais o suficiente para ter mudanças de política naquela data (por exemplo, America/Bahia_Banderas , America/Hermosillo ). Se JVM for uma dessas zonas, um programa que usa JDBC não será capaz de recuperar certos valores TIME .

Uma solução não seria recuperar usando a API antiga do JDBC e convertê-los em novas classes. Mas isso geralmente está errado:

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

Isso compila e funciona bem, exceto que não resolve nenhum dos problemas descritos acima (mesmo a recuperação da data não funciona, se a zona JVM for Pacific/Apia e a data recuperada for 2011-12-30 ;)

Agora, para a solução emergente. ResultSet tem esta API menos popular que permite que você peça ao driver JDBC para converter o tipo para você:

  • 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

Parece estar funcionando com drivers JDBC para PostgreSQL, MySQL, Oracle e H2. E, mágica, contorna os problemas de "não representabilidade na zona JVM" descritos acima.
Embora essa conversão ainda não tenha sido implementada, por exemplo, no driver do SQL Server, acho que isso poderia ser feito _o_ mapeamento padrão para classes Java Time que o JDBI envia.

Observação:
A especificação JDBC 4.2 não exige que um driver implemente isso. No entanto, a especificação requer que PreparedStatement.setObject e RowSet.setObject aceitem instâncias das classes Java Time e as tratem corretamente, então os drivers precisam oferecer suporte a essas classes explicitamente de qualquer maneira.

Isso é legal! Minha principal preocupação é que a mudança para essa abordagem possa se manifestar como uma regressão para usuários que usam drivers esotéricos. Mas talvez com a mensagem apropriada nas notas de lançamento, pudéssemos fazer essa pequena mudança tecnicamente inovadora em nome de fazer as coisas da maneira certa ...

@stevenschlansker você está certo. Eu acho que JDBI poderia fornecer

  • conjunto opcional de mapeamentos que um usuário pode conectar para restaurar o comportamento original
  • alguns comentários apropriados nas notas de lançamento (ou até mesmo um aumento na versão principal)

Vamos mantê-lo em uma versão menor, acabamos de lançar 3, e esta é apenas uma mudança significativa se você considerar errado ...;)

Apenas para reproduzir o que parece que estou ouvindo:

  • Mova os mapeadores java.time integrados existentes para um plug-in separado (gosto de YoloTimePlugin )
  • Adicione novos mapeadores integrados em seu lugar que usam ResultSet.getObject(column, type) vez de converter de tipos java.sql.
  • Documente a merda dessa mudança de última hora nas notas de versão: explique o impacto dessa mudança e quais fornecedores de banco de dados serão afetados, e o que os usuários precisam fazer para mitigar os problemas

Eu posso ficar por trás disso.

Ainda não respondemos à pergunta sobre vincular esses objetos de data / hora. Qualquer coisa que mudarmos sobre os resultados do mapeamento _ fora do_ banco de dados precisa ser espelhado na maneira como vinculamos argumentos de data / hora _ em_ instruções SQL.

Qualquer coisa que mudarmos sobre o mapeamento dos resultados do banco de dados precisa ser espelhado na maneira como vinculamos os argumentos de data / hora às instruções SQL.
@qualidafial , pergunta muito boa. Eu não tenho testado isso. Isso é explicitamente coberto pela especificação JDBC 4.2, então _deve apenas funcionar ™ _.

Isso é explicitamente coberto pela especificação JDBC 4.2, então _deve apenas funcionar ™ _.

Isso presume que os implementadores do driver JDBC seguem as especificações perfeitamente. Ainda estou para encontrar uma implementação de driver JDBC sem bugs.

Tenho a sensação de que seria muito complicado fornecer plug-ins com mapeadores para cada banco de dados e até mesmo suas diferentes versões que têm suporte diferente para tipos de dados. Talvez uma abordagem mais em branco pudesse funcionar: você começa com uma instância Jdbi sem mapeadores pré-instalados, e o artefato principal fornece um monte de mapeadores diferentes que você pode escolher manualmente para instalar, alguns com lógicas diferentes para lidar com os mesmos tipos de dados - get / setObject, get / setX, conversão para outro tipo, etc. Você precisa descobrir por si mesmo quais mapeadores são melhores para seu banco de dados (versão) e lógica de aplicativo e usar testes de unidade para mantê-los sob controle.

Isso é basicamente o que já estou fazendo agora no meu projeto. Existem alguns mapeadores pré-instalados em Jdbi que não funcionam com meu banco de dados e não preciso deles por enquanto, então, na verdade, os substituí por argument / mapper factories que lançam um UnsupportedOperationException e outros que substituí melhor implementações (veja abaixo).

Esta seria uma solução para aqueles que gostam de ficar íntimos com seu banco de dados para ter certeza de que tudo funciona absolutamente, e não mudaria nada para as pessoas que querem coisas para Just Werk ™ (na medida em que realmente faz):

  • adicione um método às instâncias Jdbi para limpar todos os mapeadores / argumentos (lista limpa)
  • expor o mapeador / arg impls integrado atual para que possamos instalar manualmente
  • continue adicionando impls mapeadores alternativos ao artefato principal quando a demanda por eles aumentar e deixe as pessoas instalá-los por conta própria, generalizando o que for possível como a seguir

Ao fazer isso, consegui encontrar ... muitos pontos no driver hsqldb onde eles se desviam de suas próprias especificações (relatados e corrigidos na fonte, ainda esperando que finalmente publiquem um artefato atualizado) e funcionou em torno dessas imperfeições, encontrando a lógica de mapeamento de trabalho sozinho.

// 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? Você poderia, por exemplo, fornecer um SetObjectArgumentFactory que precisa ser inicializado com um conjunto de classes que ele deve ativar e todos os tipos de variações de lógica de mapeamento para muitos tipos de dados, com algum comportamento configurável quando aplicável. Todo mundo feliz. Exige algum trabalho do usuário final, mas me sinto bem em saber que o jdbi faz exatamente o que eu quero e o que meu banco de dados suporta.

Tenho a sensação de que seria muito complicado fornecer plug-ins com mapeadores para cada banco de dados e até mesmo suas diferentes versões que têm suporte diferente para tipos de dados.

Eu adoraria ter plug-ins para vários fornecedores de banco de dados. Venham, venham todos: se o seu banco de dados precisa / deseja algumas customizações para adaptar o Jdbi às idiossincrasias do fornecedor do banco de dados ou de seu driver JDBC, queremos ouvir sobre isso. Ou melhor ainda, queremos solicitações pull! :)

Pontos de bônus se seu banco de dados for suportado diretamente pelo TravisCI para que possamos realmente executar testes em relação a ele: https://docs.travis-ci.com/user/database-setup/

Quanto à sua sugestão de "folha em branco", tenho apenas pequenas objeções:

  • Eu provavelmente colocaria o método clearMappings() diretamente nas classes de configuração RowMappers , ColumnMappers , Arguments e JdbiCollectors vez de Jdbi , e eu os chamaria de clear() .
  • Estou um pouco hesitante em tornar públicos os mapeadores, argumentos e coletores integrados. Alguns deles têm nomes ou designs errôneos que usamos porque são internos. Provavelmente, gostaria de refatorá-los antes de torná-los parte da API.
  • Estou questionando se a folha em branco é realmente necessária. Todas as classes de registro do Jdbi usam a abordagem last-Register-wins, portanto, sempre é possível substituir o comportamento pronto para uso. Nesse sentido, a tela em branco parece um pouco exagerada.

@ jdbi / contributors alguém mais se preocupa em opinar?

Incluí a ideia da folha em branco para evitar o uso acidental de um mapeador padrão, caso você se esqueça de registrar um de sua escolha. Eu prefiro ter um NotImplementedException do que um impl padrão. Last-wins é bom e tudo, mas não há como saber quais você precisa anular caso não queira.

Não é como se machucasse ter. Se as pessoas não quiserem essa abordagem, não precisam chamar os métodos claros e nada muda para eles. É apenas para quem prefere uma forma de trabalhar sem padrões.

Concordo que não devemos apenas tornar públicos os mapeadores existentes. Se escolhermos fornecer uma opção de lista limpa, devemos agrupar os mapeadores e fichários em Plugin pedaços razoáveis, PrimitivesPlugin , BoxedPrimitivesPlugin , CollectionsPlugin , seja o que for.

Então, podemos adicionar uma nova fábrica para o jdbi "base" sem nenhuma configuração e modificar as fábricas existentes para usar isso e adicionar WholeJdbiEnchiladaPlugin .

Eu sou um pouco contra 'claro', a menos que possamos mostrar casos em que é difícil construí-lo adicionalmente - parece um cheiro de código para mim.

Eu sou um pouco contra 'claro', a menos que possamos mostrar casos em que é difícil construí-lo adicionalmente - parece um cheiro de código para mim.

Bem, se você adicionar uma fábrica jdbi sem pré-configuração separada, então não será difícil construí-la aditivamente, então não precisaremos de clear () de fato.

Certo, acho que estamos de acordo aqui, eu estava apenas expressando uma preferência por adicionar um novo método de fábrica "limpo" em vez de um estilo clear() .

Então, isso resolve os problemas de todos? Pessoalmente, acho que o plano parece muito sexy.

  • tornar Jdbi sem padrões (lança exceções em quase tudo)
  • tornar todos os mapeadores e fichários existentes (e manipuladores tx, etc.) plugáveis ​​( PrimitivesPlugin , BoxedPrimitivesPlugin , etc), como pacotes de plug-ins e como classes individuais
  • fornecer algumas implementações alternativas ( UTCJavaTimePlugin vs LocalJavaTimePlugin vs ConvertJavaTimeToUtilDatePlugin , GetObjectMapper.forClasses(Class... cs) , SetObjectArgumentFactory.forClasses(Class... cs) , NullsToDefaultsPrimitivesPlugin vs NullThrowsExceptionPrimitivesPlugin ) e expô-los da mesma forma (em plug-ins e individualmente), para que as pessoas possam compor sua própria lógica de mapeamento total desejada, levando apenas exatamente o que desejam. Possivelmente, muitas configurações de mapeador são necessárias aqui, como estratégias diferentes para lidar com nulos ilegais ou fusos horários ausentes e outras disparidades possíveis
  • talvez faça plugins de pacote específicos de banco de dados, para que os usuários com bancos de dados + versões populares possam começar com um no-config Jdbi e instalar esquemas de mapeamento bons conhecidos em uma linha para seu banco de dados ( HsqlDb2_4_0Plugin ), novamente com opções de configuração para diferentes estratégias
  • e tornar tudo compatível com versões anteriores apenas fazendo com que os métodos de fábrica atuais executem a pré-configuração que temos agora ( BuiltInGenericPreconfigurationPlugin ), junto com os métodos de fábrica sem configuração.

tornar Jdbi sem padrões

Não tenho uma opinião muito forte, mas tudo isso parece muito complexo da perspectiva do usuário. Os usuários precisarão compreender os vários mapeamentos possíveis para os tipos que desejam usar e escolher um apropriado. Isso é difícil, especialmente quando os temporais estão em jogo - realmente não é trivial entender as diferentes opções possíveis.

Os usuários precisarão entender os vários mapeamentos possíveis para os tipos que desejam usar e escolher um apropriado

Não, apenas se eles quiserem. Os métodos de fábrica existentes continuarão gerando Jdbi instâncias com exatamente os mesmos mapeadores pré-instalados que eles fazem agora. Além disso, obteremos métodos de fábrica de configuração DIY, e as pessoas que optarem por eles precisarão descobrir as intimidades do mapeamento. Haverá um meio do caminho também, onde você obtém uma instância DIY e apenas instala o YourDbAndVersionPlugin e executa o que quer que ele faça. Minha longa explicação foi principalmente sobre componentes internos e uso avançado de jdbi, não a linha de base.

TLDR: Você ainda será capaz de fazer Jdbi.create(dataSource) e não precisará dar mais explicações sobre isso que ainda não fez. Alguém simplesmente escolherá Jdbi.createBlank(dataSource).install(x).install(y).install(z)...

Eu estou a bordo, exceto que não acho que devemos descontinuar as fábricas existentes, acredito que a maioria dos usuários continuará a usá-lo, pois o comportamento "pronto para usar" é muito bom.

É justo

@TheRealMarnes Toda essa conversa começou lidando com tipos de dados JSR-310 que não são suportados diretamente pelo JDBC.

Acho que há um consenso sobre a remoção dos mapeadores e argumentos errantes java.time e colocá-los em um plug-in em vez de embutidos.

Você ainda quer perseguir isso?

Apenas os java.time? Um JavaTimePlugin?

Sim, um plugin apenas para tipos java.time, mas nomeado para comunicar que os argumentos e mapeadores são implementações ingênuas e com perdas, conforme descrito por @findepi .

SimplisticJavaTimePlugin ?

Esperando com isso até que meus outros PRs sejam atendidos ... É um pouco demais ao mesmo tempo.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

goxr3plus picture goxr3plus  ·  4Comentários

nonameplum picture nonameplum  ·  5Comentários

buremba picture buremba  ·  5Comentários

Shujito picture Shujito  ·  5Comentários

bakstad picture bakstad  ·  5Comentários