Projetos e práticas para proteção contra entradas nulas erradas do banco de dados

9

Uma parte do meu programa busca dados de muitas tabelas e colunas no meu banco de dados para processamento. Algumas das colunas podem estar null, mas no contexto de processamento atual, isso é um erro.

Isso "teoricamente" não deve acontecer, portanto, se isso ocorrer, ele indica dados incorretos ou um bug no código. Os erros têm gravidades diferentes, dependendo de qual campo é null; ou seja, para alguns campos o processamento deve ser interrompido e alguém notificado, para outros o processamento deve continuar e apenas notificar alguém.

Existem bons princípios de arquitetura ou design para lidar com as nullentradas raras, mas possíveis ?

As soluções devem ser possíveis de implementar com Java, mas eu não usei a tag porque acho que o problema é um pouco independente da linguagem.


Alguns pensamentos que eu tinha:

Usando NOT NULL

O mais fácil seria usar uma restrição NOT NULL no banco de dados.

Mas e se a inserção original dos dados for mais importante que esta etapa de processamento posterior? Portanto, caso a inserção coloque um nullna tabela (por causa de bugs ou talvez por algum motivo válido), eu não gostaria que a inserção falhasse. Digamos que muitas outras partes do programa dependam dos dados inseridos, mas não dessa coluna em particular. Portanto, prefiro arriscar o erro na etapa de processamento atual em vez da etapa de inserção. É por isso que não quero usar uma restrição NOT NULL.

Ingenuamente, dependendo de NullPointerException

Eu poderia apenas usar os dados como se esperasse que eles estivessem sempre lá (e esse deveria realmente ser o caso) e capturar os NPEs resultantes em um nível apropriado (por exemplo, para que o processamento da entrada atual pare, mas não todo o progresso do processamento ) Esse é o princípio do "falhar rápido" e eu geralmente prefiro. Se for um bug, pelo menos, recebo um NPE registrado.

Mas, então, perco a capacidade de diferenciar entre vários tipos de dados ausentes. Por exemplo, para alguns dados ausentes, eu poderia deixar de fora, mas para outros, o processamento deve ser interrompido e um administrador notificado.

Verificando nullantes de cada acesso e lançando exceções personalizadas

Exceções personalizadas me permitem decidir a ação correta com base na exceção, portanto esse parece ser o caminho a seguir.

Mas e se eu esquecer de verificar em algum lugar? Além disso, desorganizo meu código com verificações nulas que nunca ou raramente são esperadas (e, portanto, definitivamente não fazem parte do fluxo da lógica de negócios).

Se eu optar por seguir esse caminho, quais padrões são mais adequados para a abordagem?


Quaisquer pensamentos e comentários sobre minhas abordagens são bem-vindos. Também melhores soluções de qualquer tipo (padrões, princípios, melhor arquitetura do meu código ou modelos etc.).

Editar:

Há outra restrição: eu estou usando um ORM para fazer o mapeamento do banco de dados para o objeto de persistência, portanto, fazer verificações nulas nesse nível não funcionaria (como os mesmos objetos são usados ​​em partes em que o nulo não causa nenhum dano) . Eu adicionei isso porque as respostas fornecidas até agora mencionaram essa opção.

jhyot
fonte
5
"Algumas das colunas podem ser nulas, mas no atual contexto de processamento, isso é um erro. ... caso a inserção coloque um nulo na tabela, eu não gostaria que a inserção falhasse." Esses dois requisitos são contraditório. É impossível encontrar uma solução até que você relaxe uma das duas condições.
Kilian Foth
@KilianFoth Bem, meu relaxamento é que o erro no contexto de "processamento atual" é menos grave do que ao inserir. Portanto, aceito erros de processamento raros, mas quero ter um bom design robusto para lidar com eles. É por isso que NOT NULL, que seria uma boa solução, não é possível aqui.
jhyot
11
Se você aceitar tantos erros, os criadores desses erros nunca os corrigirão. Se suas declarações bagunçadas de inserção forem bem-sucedidas, que incentivo eles terão para consertar as coisas? Você considera robusto não falhando, mas aceitando dados incorretos?
Tulains Córdova
@ user61852 Não estou explicitamente aceitando os erros, mas quero tratá-los normalmente. Engolir ponteiros nulos está fora de questão. Além disso, e se minha peça for realmente objetivamente (conforme definida pela empresa) menos importante que muitas outras partes que exigem que a inserção seja bem-sucedida, mas não exigem que esse campo específico seja definido? As inserções não se originam de uma entrada de usuário onde eu poderia forçá-las a adicionar o valor, mas de outro código em que a omissão provavelmente é um bug (mas não é importante o suficiente para interromper a inserção).
jhyot
11
Marcá-los como NOT NULL no banco de dados seria a melhor solução, se uma coluna for anulável, o código precisará lidar com o caso quando for, mesmo que não seja esperado porque o mecanismo de armazenamento permite.
Jon Raynor

Respostas:

9

Eu colocaria as verificações nulas no seu código de mapeamento, onde você constrói seu objeto a partir do conjunto de resultados. Isso coloca a verificação em um só lugar e não permitirá que seu código passe pela metade do processamento de um registro antes de ocorrer um erro. Dependendo de como o fluxo do aplicativo funciona, convém executar o mapeamento de todos os resultados como uma etapa de pré-processamento, em vez de mapear e processar cada registro, um de cada vez.

Se você estiver usando um ORM, precisará executar todas as suas verificações nulas antes de processar cada registro. Eu recomendaria um recordIsValid(recordData)método -type, para que você possa (novamente) manter toda a lógica de verificação nula e outra validação em um só lugar. Definitivamente, não misturaria as verificações nulas com o restante da sua lógica de processamento.

TMN
fonte
Obrigado, essa é uma boa visão! Na verdade, estou usando um ORM, portanto, as verificações nesse nível não funcionarão. Mas também tenho algum mapeamento para objetos de domínio real a partir dos objetos de persistência. Vou verificar se é possível fazer o mapeamento e a validação em uma etapa de pré-processamento.
jhyot
E se você alternar seu ORM, e então? Melhor defender isso na fonte (veja a resposta do Doc Brown).
Robbie Dee
@RobbieDee: Não deveria importar. Se você precisar reescrever o código de mapeamento, as verificações nulas estarão lá e você as modificará como parte da reescrita ou terá um método separado que executa as verificações nulas nos objetos de negócios, para que não seja necessário reescrever. E, como implica o Doc Brown, às vezes é importante notar que faltam dados, em vez de encobrir esse fato com um valor padrão.
TMN
Isso deve acontecer ainda mais no fluxo de ETL. Você ainda corre o risco de duplicar esforços dessa maneira.
Robbie Dee
6

Parece que inserir um nulo é um erro, mas você tem medo de aplicar esse erro na inserção porque não deseja perder dados. No entanto, se um campo não deve ser nulo, mas sim, você está perdendo dados . Portanto, a melhor solução é garantir que os campos nulos não sejam salvos erroneamente em primeiro lugar.

Para esse fim, imponha que os dados estejam corretos no repositório permanente autorizado e autorizado para esses dados, o banco de dados. Faça isso adicionando restrições não nulas. Em seguida, seu código poderá falhar, mas essas falhas notificarão você imediatamente sobre erros, permitindo corrigir problemas que já estão causando a perda de dados. Agora que você pode facilmente identificar erros, teste seu código e duas vezes. Você poderá corrigir os erros que levam à perda de dados e, no processo, simplificar bastante o processamento posterior dos dados, porque não precisará se preocupar com valores nulos.

Restabelecer Monica
fonte
2
Obrigado pela resposta. Concordo que sua solução é a maneira certa de fazê-lo, e você a formulou de forma concisa. Restrições externas à minha influência podem dificultar ou impossibilitar (por exemplo, recursos indisponíveis para teste ou para tornar o código existente automaticamente testável), mas eu definitivamente devo verificar se essa solução pode funcionar antes de tentar outras maneiras. No meu pensamento original, talvez eu tenha assumido muito rapidamente que não posso resolver o problema na fonte.
jhyot
@jhyot Okay. É frustrante quando você não pode fazer as coisas da maneira limpa. Espero que minha resposta seja pelo menos útil para pessoas que têm problemas semelhantes, mas que são capazes de atacar a causa raiz, em vez de limpar a bagunça depois do fato.
Reintegrar Monica
5

Em relação a esta sentença na pergunta:

Isso "teoricamente" não deve acontecer, portanto, se isso ocorrer, ele indica dados incorretos ou um bug no código.

Eu sempre apreciei esta citação (cortesia deste artigo ):

Eu acho divertido quando programadores iniciantes acreditam que seu trabalho principal é impedir que programas falhem. Imagino que esse argumento espetacular de falha não seria tão atraente para um programador assim. Programadores mais experientes percebem que o código correto é ótimo, o código que trava pode melhorar, mas o código incorreto que não trava é um pesadelo horrível.

Basicamente: parece que você está endossando a Lei de Postel , "seja conservador no que envia, seja liberal no que aceita". Embora seja ótimo em teoria, na prática, esse "princípio de robustez" leva a um software que não é robusto , pelo menos a longo prazo - e às vezes também a curto prazo. (Compare o artigo de Eric Allman, O princípio da robustez reconsiderado , que é um tratamento muito completo do assunto, embora principalmente focado nos casos de uso de protocolos de rede.)

Se você possui programas que estão inserindo dados incorretamente no banco de dados, esses programas estão danificados e precisam ser corrigidos . Cobrir o problema apenas permite que ele continue piorando; este é o equivalente da engenharia de software de permitir que um viciado continue seu vício.

Pragmaticamente falando, no entanto, às vezes você precisa permitir que o comportamento "quebrado" continue, pelo menos temporariamente, especialmente como parte de uma transição contínua de um estado frouxo e frouxo para um estado estrito e correto. Nesse caso, você deseja encontrar uma maneira de permitir que as inserções incorretas tenham êxito, mas ainda permita que o armazenamento de dados "canônico" esteja sempre em um estado correto . Existem várias maneiras de fazer isso:

  • Use um gatilho de banco de dados para converter inserções malformadas em inserções corretas, por exemplo, substituindo valores ausentes / nulos por padrões
  • Faça com que os programas incorretos sejam inseridos em uma tabela de banco de dados separada que possa estar "incorreta" e possua um processo agendado separado ou outro mecanismo que mova os dados corrigidos dessa tabela para o armazenamento de dados canônico
  • Use a filtragem do lado da consulta (por exemplo, uma visualização) para garantir que os dados recuperados do banco de dados estejam sempre em um estado correto, mesmo se os dados em repouso não estiverem disponíveis.

Uma maneira de contornar todos esses problemas é inserir uma camada de API que você controla entre os programas que emitem gravações e o banco de dados real.

Parece que parte do seu problema é que você nem conhece todos os lugares que estão gerando gravações incorretas - ou simplesmente existem muitos deles para atualizar. É um estado assustador, mas nunca deveria ter sido permitido surgir.

Assim que você tiver mais de um punhado de sistemas com permissão para modificar dados em um armazenamento de dados de produção canônico, você estará com problemas: não há como manter centralmente nada sobre esse banco de dados. Melhor seria permitir que o menor número de processos possível emitisse gravações e os usasse como "gatekeepers" que podem pré-processar os dados antes de inseri-los conforme necessário. O mecanismo exato para isso realmente depende da sua arquitetura específica.

Daniel Pryden
fonte
"Se você possui programas que estão inserindo dados incorretamente no banco de dados, esses programas estão danificados e precisam ser corrigidos." isso também é ótimo em teoria, mas a realidade é que eles ainda estarão adicionando registros enquanto algum comitê continua a debater sobre o uso de "NA" ou "Nenhum".
JeffO 6/01/16
@ Jeff: Nenhum comitê deve discutir se deve armazenar "NA", "Nenhum", NULL ou qualquer outra coisa no banco de dados. As partes interessadas não técnicas têm interesse em quais dados saem do banco de dados e como são usados, mas não na representação interna.
Daniel Pryden
@DanielPryden: No meu último trabalho, tínhamos um Conselho de Revisão de Arquitetura (com um subcomitê de DBA) que revisava as alterações técnicas entre domínios. Muito técnico, mas eles se reuniam apenas a cada duas semanas e se você não fornecesse detalhes suficientes para eles, eles adiariam uma decisão até que você o fizesse ... em uma reunião subsequente. A maioria das alterações não triviais do sistema, que não consistiam em adicionar funcionalidade por meio de novo código, normalmente levavam um mês ou mais.
TMN
@ DanielPryden - participei de reuniões com debates da alta gerência nos rótulos das caixas de texto. Você pode argumentar que isso não tem nada a ver com o que você irá nomear no aplicativo ou no banco de dados, mas sim.
Jeffo
Em resposta a comentários sobre como obter aprovações adicionais para alterações desse tipo: meu argumento sobre os valores serem "incorretos" pressupõe que os valores permitidos já estejam documentados em algum lugar - é por isso que o OP diz que esses valores devem ser considerados um bug. Se o esquema do banco de dados for especificado para permitir um valor, esse valor não será um erro. O ponto é que, se você possui dados que não correspondem ao seu esquema, algo está quebrado: sua prioridade deve ser fazer com que os dados e o esquema correspondam. Dependendo da equipe, isso pode envolver a alteração dos dados, do esquema ou de ambos.
Daniel Pryden
2

" Existem bons princípios de arquitetura ou design para lidar com as entradas nulas raras, mas possíveis? "

Resposta simples - sim.

ETL

Realize algum processamento inicial para garantir que os dados tenham qualidade suficiente para entrar no banco de dados. Qualquer coisa no arquivo suspenso deve ser relatada novamente e todos os dados limpos podem ser carregados no banco de dados.

Como alguém que tem sido caçador (dev) e detentor de jogos (DBA), sei por experiência amarga que terceiros simplesmente não resolverão seus problemas de dados, a menos que sejam forçados a fazê-lo. Constantemente curvando-se para trás e massageando dados através de conjuntos de um precedente perigoso.

Mart / Repositório

Nesse cenário, os dados brutos são enviados para o banco de dados do repositório e, em seguida, uma versão higienizada é enviada para o banco de dados do mercado a que os aplicativos têm acesso.

Valores padrão

Se você pode aplicar valores padrão sensíveis às colunas, deve fazê-lo, embora isso possa envolver algum trabalho, se este for um banco de dados existente.

Falhar cedo

É tentador simplesmente resolver problemas de dados no gateway para o aplicativo, conjunto de relatórios, interface etc. Recomendamos que você não confie apenas nisso. Se você conectar algum outro widget ao banco de dados, será possível enfrentar os mesmos problemas novamente. Resolva os problemas de qualidade dos dados.

Robbie Dee
fonte
+1 É o que eu faria, coletaria todos os dados e criaria um conjunto de dados válido para o seu aplicativo processar.
Kwebble #
1

Sempre que seu caso de uso permitir substituir NULL com segurança por um bom valor padrão, você poderá fazer a conversão nas SELECTinstruções Sql usando ISNULLou COALESCE. Então, ao invés de

 SELECT MyColumn FROM MyTable

alguém pode escrever

 SELECT ISNULL(MyColumn,DefaultValueForMyColumn) FROM MyTable

Obviamente, isso só funcionará quando o ORM permitir manipular diretamente as instruções de seleção ou fornecer modelos alteráveis ​​para a geração. Deve-se garantir que nenhum erro "real" seja mascarado dessa maneira; portanto, aplique-o apenas se a substituição por um valor padrão for exatamente o que você deseja no caso de NULL.

Se você conseguir alterar o banco de dados e o esquema, e o sistema db suportar isso, considere adicionar uma cláusula de valor padrão às colunas específicas, conforme sugerido por @RobbieDee. No entanto, isso também exigirá modificar os dados existentes no banco de dados para remover quaisquer valores NULL inseridos anteriormente e removerá a capacidade de distinguir os dados de importação corretos e incompletos posteriormente.

Pela minha própria experiência, eu sei que usar o ISNULL pode funcionar surpreendentemente bem - no passado, eu tive que manter um aplicativo legado em que os desenvolvedores originais haviam esquecido de adicionar restrições NOT NULL a muitas colunas e não pudemos adicioná-las facilmente mais tarde. por algumas razões. Mas em 99% de todos os casos, 0 como padrão para colunas numéricas e a sequência vazia como padrão para colunas de texto eram totalmente aceitáveis.

Doc Brown
fonte
Enquanto isso funciona, você pode ter que duplicar o código defensivo de cada SELECT. Uma abordagem muito melhor é definir um valor padrão para uma coluna quando um NULL é inserido, embora isso possa não ser possível / desejável por vários motivos.
Robbie Dee
@RobbieDee: obrigado por esse comentário, mudei minha resposta de acordo. No entanto, se isso é "muito melhor", é discutível. Quando o código CRUD está em um só lugar, o código defensivo duplicado pode não ser um grande problema. E se não for, já existe alguma duplicação de código de antemão.
Doc Brown
Operações CRUD simples são obviamente o ideal. Porém, no mundo real, os sistemas geralmente têm visualizações complexas da interface do usuário, assistentes de dados gerados pelo usuário, relatórios etc. etc. O que você descreveu pode ser preferível em um desenvolvimento brownfield.
Robbie Dee
Melhor resposta. Novos aplicativos geralmente adicionam novos dados que podem estar fora de seu controle. NULLs errados geralmente vêm da importação de dados herdados para bancos de dados reprojetados. As restrições são desativadas para permitir a conclusão em algumas horas, em vez de vários dias. "O grande fracasso" geralmente ocorre quando os DBAs tentam reativar as restrições. Como nunca foi planejado, o gerenciamento geralmente rejeita as semanas de trabalho necessárias para corrigir os dados incorretos, e assim permanece. Todos os aplicativos devem lidar com NULLs normalmente, inserindo padrões e relatórios ou solicitando os dados ausentes.
DocSalvager
1

O OP está assumindo uma resposta que combina as regras de negócios com os detalhes técnicos do banco de dados.

Isso "teoricamente" não deve acontecer, portanto, se isso ocorrer, ele indica dados incorretos ou um bug no código. Os erros têm gravidades diferentes, dependendo de qual campo é nulo; ou seja, para alguns campos o processamento deve ser interrompido e alguém notificado, para outros o processamento deve continuar e apenas notificar alguém.

Isso é todas as regras de negócios. As regras de negócios não se importam com nulo per se. Pelo que se sabe, o banco de dados pode ter nulo, 9999, "BOO!" ... É apenas outro valor. Que, em um RDBMS, null tem propriedades interessantes e usos exclusivos é discutível.

A única coisa que importa é o que "nulidade" significa para o (s) objeto (s) de negócios especificado (s) ...

Existem bons princípios de arquitetura ou design para lidar com as entradas nulas raras, mas possíveis?

Sim.

  • Coloque regras de negócios nas classes.
  • A transliteração deve estar em uma camada de código apropriada, dissociando as classes de negócios e o armazenamento de dados. Se você não pode colocá-lo no código ORM, pelo menos, não o coloque no banco de dados.
  • Torne o banco de dados o mais burro possível, sem regras de negócios aqui. Mesmo coisas inócuas, como deixar um valor por padrão, vão te morder . Esteve lá.
  • Valide os dados indo e vindo do banco de dados. E é claro que isso é feito no contexto dos objetos de negócios.

Lançar uma exceção na recuperação de dados não faz sentido.

A questão é "devo armazenar dados 'ruins'"? Depende:

  • Dados incorretos podem ser usados - nunca salve objetos inválidos ou composições de objetos. Dados complexos / relações comerciais em todo o lugar. Os usuários podem executar qualquer função a qualquer momento, possivelmente usando essa entidade comercial em vários contextos. O efeito (se houver) de dados incorretos, no momento em que são salvos, não é conhecido porque depende muito do uso futuro. Não há um processo unificado / único desses dados.
  • Não é possível progredir se houver dados incorretos - permita salvar dados incorretos. No entanto, a próxima etapa de um processo não pode continuar até que tudo seja válido. Por exemplo, fazendo um imposto de renda. Quando recuperado do banco de dados, o software aponta os erros e não pode ser enviado ao IRS sem verificação de validade.
radarbob
fonte
0

Existem várias maneiras de lidar com nulos, portanto, passaremos da camada do banco de dados para a camada do aplicativo.


Camada de banco de dados

Você pode proibir nulos ; embora aqui seja impraticável.

Você pode configurar um padrão por coluna:

  • requer que a coluna esteja ausente do insert, portanto, não cobre inserção nula explícita
  • impede a detecção de linhas em que a insertcoluna erroneamente errou

Você pode configurar um gatilho para que, após a inserção, os valores ausentes sejam calculados automaticamente:

  • requer que as informações necessárias para realizar esse cálculo estejam presentes
  • desacelerará o insert

Camada de consulta

Você pode pular linhas onde um inconveniente nullestá presente:

  • simplifica a lógica principal
  • impede a detecção de "linhas defeituosas"; portanto, outro processo seria necessário para verificá-las
  • requer que cada consulta seja instrumentada

Você pode fornecer um valor padrão na consulta:

  • simplifica a lógica principal
  • impede a detecção de "linhas defeituosas"; portanto, outro processo seria necessário para verificá-las
  • requer que cada consulta seja instrumentada

Nota: instrumentar cada consulta não é necessariamente um problema se você tiver alguma maneira automatizada de gerá-las.


Camada de aplicação

Você pode verificar previamente a tabela como proibido null:

  • simplifica a lógica principal
  • melhora o tempo até a falha
  • requer manter a lógica de pré-verificação e aplicação consistente

Você pode interromper o processamento ao encontrar um proibido null:

  • evita duplicar o conhecimento de quais colunas podem ser nulle quais não podem
  • ainda é relativamente simples (apenas um cheque + retorno / lançamento)
  • requer que seu processo seja retomado (se você já enviou um email, não deseja enviá-lo duas ou cem vezes!)

Você pode pular a linha ao encontrar um proibido null:

  • evita duplicar o conhecimento de quais colunas podem ser nulle quais não podem
  • ainda é relativamente simples (apenas um cheque + retorno / lançamento)
  • não exige que seu processo seja retomado

Você pode enviar uma notificação ao encontrar um proibido null, um de cada vez ou por lote, que é complementar às outras formas apresentadas acima. O que importa mais, no entanto, é "o que é então?", Mais notavelmente, se você espera que a linha seja corrigida e precise ser processada novamente, talvez seja necessário garantir que você tenha alguma maneira de distinguir as linhas já processadas das linhas que precisam de sendo processado novamente.


Dada a sua situação, eu lidaria com a situação no aplicativo e combinaria:

  • interromper e notificar
  • pular e notificar

Eu tenderia a pular, se possível, de alguma forma, garantir um pouco de progresso, especialmente se o processamento levar algum tempo.

Se você não precisar reprocessar as linhas ignoradas, simplesmente registrá-las deve ser suficiente e um e-mail enviado no final do processo com o número de linhas ignoradas será uma notificação adequada.

Caso contrário, eu usaria uma tabela lateral para as linhas serem corrigidas (e processadas novamente). Essa tabela lateral pode ser uma referência simples (sem chave estrangeira) ou uma cópia completa: a última, mesmo que mais cara, é necessária se você não tiver tempo para resolver a questão nullantes de limpar os dados principais.

Matthieu M.
fonte
-1

Nulos podem ser manipulados na tradução ou mapeamento de tipos de banco de dados para tipos de idioma. Por exemplo, em C #, aqui está um método genérico que lida com nulo para você para qualquer tipo:

public static T Convert<T>(object obj)
        {
            if (obj == DBNull.Value)
            {
                return default(T);
            }

            return (T) obj;
        }

public static T Convert<T>(object obj, T defaultValue)
        {
            if (obj == DBNull.Value)
            {
                T t = defaultValue;
                return t;
            }

            return (T) obj;
        }

Ou, se você deseja executar uma ação ...

 public static T Convert<T>(object obj, T defaultValue)
        {
            if (obj == DBNull.Value)
            {
                //Send an Alert, we might want pass in the name
                //of column or other details as well
                SendNullAlert();
                //Set it to default so we can keep processing
                T t = defaultValue;
                return t;
            }

            return (T) obj;
        }

E então no mapeamento, neste caso para um objeto do tipo "Amostra", manipularemos null para qualquer uma das colunas:

public class SampleMapper : MapperBase<Sample>
    {
        private const string Id = "Id";
        private const string Name = "Name";
        private const string DataValue = "DataValue";
        private const string Created = "Created";

        protected override Sample Map(IDataRecord record)
        {
            return new Sample(
                Utility.Convert<Int64>(record[Id]),
                Utility.Convert<String>(record[Name]),
                Utility.Convert<Int32>(record[DataValue]),
                Utility.Convert<DateTime>(record[Created])
                );
        }
    }

Por fim, todas as classes de mapeamento podem ser geradas automaticamente com base na consulta ou nas tabelas SQL envolvidas, observando os tipos de dados SQL e convertendo-os para os tipos de dados específicos do idioma. Isso é o que muitos ORMs fazem por você automaticamente. Observe que alguns tipos de banco de dados podem não ter um mapeamento direto (colunas geoespaciais etc.) e podem precisar de tratamento especial.

Jon Raynor
fonte
Se alguém quiser postar a versão equivalente Java que seria ótimo ...
Jon Raynor
Eu acho que o código de exemplo é perfeitamente compreensível também para desenvolvedores de Java. Na minha situação, eu já tenho um ORM em vigor, portanto, não preciso implementar um. Mas sua resposta aborda apenas os valores padrão para nulos, enquanto no meu caso, na verdade, o caso muito mais importante é detectar um nulo e acionar uma ação (por exemplo, informe um administrador sobre os dados errados).
jhyot
Ahhh, vou atualizar minha resposta com base nisso.
Jon Raynor
Seu código editado agora tem uma ação padrão para qualquer valor nulo (ou seja, é completamente genérico). Isso é muito parecido com a minha segunda opção na pergunta original, ou seja, basta jogar nulo e pegá-lo em algum lugar. Mas, como afirmado lá, preciso diferenciar as ações com base em qual valor está faltando.
jhyot