Como o Hibernate quase arruinou minha carreira

Publicados: 2022-03-11

Imagine que você é um desenvolvedor Java e está prestes a iniciar seu próximo grande projeto. Você precisa tomar as decisões fundamentais que ficarão com você pelo resto do projeto. Você deseja escolher a melhor abstração orientada a objetos de seu modelo de dados flexível porque não deseja lidar com SQL simples. Você deseja oferecer suporte a todos os tipos de dados e, idealmente, suporte a todos os tipos de bancos de dados.

A resposta óbvia é apenas usar Hibernate , certo? 90% dos desenvolvedores Java concordam com você, mas isso faz com que seja a decisão certa?

Vamos dar uma olhada no que pode dar errado se você usar o Hibernate cegamente apenas porque é o padrão aceito.

Considere Monica, uma desenvolvedora Java. Monica foi recentemente promovida ao cargo de arquiteta e agora é responsável pelo layout da pilha de tecnologia para um novo produto em sua empresa. Ela sabe que no mundo Java só existe uma boa ferramenta para lidar com a comunicação do banco de dados: Hibernate . Hibernate é um padrão JPA bem conhecido e suportado. No entanto, é sempre uma boa ideia verificar algumas coisas antes de iniciar um projeto. Felizmente, seu colega, Ben, conhece o cara certo.

Hibernar soa como uma bala de prata

4 anos atras

Ben - Olá Monica, gostaria de apresentar o John. Ele é um especialista em Hibernate e vai ajudá-lo.

Monica - Ei John, que bom que você encontrou algum tempo para mim. Então, estamos construindo nossa Próxima Grande Coisa, você sabe. Estamos planejando nos tornar o próximo Facebook ou Google. Dias ocupados. Vai ser enorme. Absolutamente fantástico! Todo mundo está tão animado! Fui promovido ao cargo de arquiteto, então agora tenho que selecionar a pilha que usaremos. A única parte que falta é a persistência…

John - Hiberna !

Mônica - Sim! Exatamente! Apenas o que eu estava pensando! Parece uma combinação perfeita e o negócio real para nós. Uma verdadeira solução empresarial para um verdadeiro problema empresarial, comprovada pelo mercado e com uma longa história. Já ouvi muitas experiências positivas com ele. No entanto, tenho um problema com um de nossos companheiros de equipe; ele é totalmente contra. Ele sabe muito sobre bancos de dados e tem medo de adicionar outra camada entre nosso aplicativo e o banco de dados. Ele é super inteligente, e eu preciso de alguns argumentos muito bons para convencê-lo de que esta é uma boa decisão. Você pode me ajudar com isso?

João - Claro! Eu ficarei feliz em. O Hibernate é, de fato, uma ferramenta excelente. É amplamente utilizado em grandes e verdadeiras soluções empresariais, como bancos. Você não pode errar com isso. Pense em persistência: escolha Hibernate . Se você está escrevendo em Java, esta é absolutamente a escolha certa, além de ter portas para outras linguagens. Veja quantas descrições de cargos exigem isso!

Mônica - Concordo plenamente! Eu tenho os mesmos sentimentos sobre isso. Em um projeto anterior, estávamos usando principalmente SQL via JDBC simples e antigo. Ridículo! Eu sei! Mas, eis a coisa: temos caras SQL realmente inteligentes na equipe e quando eles viram o SQL gerado pelo Hibernate ficaram nervosos. Parecia feio e ilegível; isso será um problema no futuro?

João - Olha. Os caras do DBA têm uma perspectiva diferente. Eles têm medo do Hibernate porque parece substituir seu papel no projeto. Além disso, os bancos de dados possuem otimizadores de consulta integrados, portanto, você não precisa se preocupar com a aparência dessas consultas. O banco de dados irá otimizá-lo para você. É tudo uma questão de desenvolvimento rápido, o que o SQL não pode fazer.

Mônica - Sério?! Não está mais lidando com SQL? Incrível! A última vez que um DBA passou semanas tentando otimizar algumas consultas. Semanas! Oh, eu me sinto tão envergonhado de dizer isso a você, mas você sabia que estávamos usando... procedimentos armazenados (risos). Ah, foi uma bagunça. Dá para acreditar que o projeto ainda está usando? Eu sinto muito pelas pessoas lá fora. Eles ainda precisam escrever esse código tedioso repetidamente. Gostaria de saber se ainda é um projeto Java ou SQL?

John - Essa é exatamente a diferença entre uma abordagem orientada a objetos e a relacional. É a chamada incompatibilidade de impedância orientada a objetos. O Hibernate pode fechar essa lacuna. Os desenvolvedores podem se concentrar na construção de lógica de negócios. Os recursos de push deixam as partes interessadas e toda a gerência felizes. Faça as coisas que mais importam: Negócios! Muitos códigos padronizados desaparecerão e você terá uma conexão mágica, invisível, mas confiável, entre a lógica e os dados.

Mônica - Cooperação mútua. Sinergia total. Como se o banco de dados fizesse parte da linguagem desde o início. Estou tão feliz por ser um líder deste salto tecnológico de fé. É como a velocidade de dobra na jornada do software.

João - Sim! Você conseguiu!

Monica - Oh meu Deus, estou tão animada! Obrigado, João! Estou pronto!

O Hibernate não é uma bala de prata. Não o trate como sua solução de banco de dados padrão.
Tweet

Dores de crescimento com soluções não flexíveis

3 anos atrás

Monica - Ei John, lembra do projeto que falamos no ano passado?

João - Claro. Como tá indo?

Monica - Em breve iremos para a produção. Está tudo bem, mas algumas perguntas surgiram.

John - Claro, me bata.

Monica - Bem, não podemos mais gerar nosso esquema de banco de dados do zero. Qual é a melhor maneira de oferecer suporte a alterações de esquema sem perder dados?

John - Bem, primeiro, o Hibernate não se destina a ser usado como ferramenta de migração de produção. Use algo como FlywayDB ou Liquibase. É bem simples. Você anota os scripts de migração e, em seguida, atualiza o modelo de entidade junto com os mapeamentos do Hibernate , para que ele fique sincronizado com a estrutura real do banco de dados.

Mônica - Hum, entendi. Estávamos usando apenas a migração SQL simples no projeto anterior.

João - Tudo bem também. Contanto que você mantenha o modelo de entidade e o esquema sincronizados, faça como quiser.

Mônica - Entendi. Há outra coisa. Estamos sempre lutando com problemas de busca preguiçosos/ansiosos. A certa altura, resolvemos fazer tudo avidamente, mas parece abaixo do ideal e, além disso, às vezes não é possível acessar alguns campos porque não há sessão, ou algo assim. Isso é normal?

John - Você precisa aprender mais sobre o Hibernate . O mapeamento do banco de dados não é simples. Basicamente, existem várias maneiras de fazê-lo. Você só precisa escolher uma maneira que funcione para você. A busca lenta oferece a capacidade de carregar esses objetos sob demanda, mas você precisa operar em uma sessão ativa.

Monica - Ainda estamos lutando com qual mecanismo de banco de dados usar para a implantação final. Eu pensei que o Hibernate fosse portátil, mas temos algumas consultas nativas que usam alguma mágica do MS SQL, e na verdade gostaríamos de usar o MySQL na produção.

John - O Hibernate oferece flexibilidade desde que você esteja usando critérios separados ou HQL; quaisquer consultas nativas apenas vincularão sua solução ao banco de dados.

Monica - Parece que temos que nos ater ao MS SQL então. Última pergunta: Meu companheiro de equipe disse que não há palavra-chave “limite” em HQL. Achei que ele estava brincando, mas também não consegui achar. Desculpe pela pergunta estúpida…

John - De fato, não há palavra-chave “limite” em HQL. Você pode controlar isso por meio do objeto de consulta, pois é específico do fornecedor do banco de dados.

Monica - Parece estranho que todos os outros elementos estejam em HQL. Deixa pra lá. Obrigado pelo seu tempo!

Relacionado: Como construir um aplicativo multilocatário: um tutorial de hibernação

Agora estamos hackeando juntos soluções em SQL novamente

2 anos atrás

Monica - John, no começo não íamos lidar com SQL, mas agora parece que temos que fazer. Nossas necessidades estão crescendo, e parece que não há como contornar isso. Parece errado, mas começamos a usar SQL novamente diariamente.

John - Bem, não está errado. Você não precisava se concentrar no banco de dados no início. No entanto, à medida que o projeto cresce, é bom usar SQL e trabalhar na otimização do desempenho.

Monica - Às vezes a gente fica dias procurando erros. Parece que temos que analisar o SQL gerado pelo Hibernate porque não temos ideia de por que ele não está funcionando como esperado e está produzindo resultados inesperados. Encontramos alguns problemas que são bem conhecidos no rastreador de bugs do Hibernate . Além disso, é difícil escrever migrações adequadas mantendo o modelo de entidade sincronizado. É demorado, pois precisamos aprender muito sobre os componentes internos do Hibernate e prever como ele funcionará.

John - Há sempre uma curva de aprendizado. Você não precisa escrever muito, mas precisa saber como funciona.

Monica - Trabalhar com conjuntos de dados maiores também é chato. Recentemente, fizemos uma importação massiva para o banco de dados, e foi dolorosamente lento. Então descobrimos que tínhamos que limpar a sessão para torná-la mais rápida. Mesmo assim, ainda é significativamente mais lento, então decidimos reescrevê-lo como instruções SQL simples. O engraçado é que escrever SQL simples era na verdade a maneira mais rápida de fazer isso, então decidimos fazê-lo como nossa última opção.

John - A importação não é um processo orientado a objetos. O Hibernate se concentra no design orientado a objetos. Lembre-se de que você sempre pode usar consultas nativas.

Monica - Você pode me ajudar a entender como funciona o cache do Hibernate ? Eu simplesmente não entendo. Existem alguns caches de primeiro/segundo nível. O que é isso tudo?

João - Claro. É o chamado cache de nível de transação de dados persistentes. É possível configurar um cache de nível de cluster ou JVM em uma base de classe por classe e coleção por coleção. Você pode até conectar um cache clusterizado. Mas lembre-se de que os caches não estão cientes de nenhuma alteração feita no armazenamento persistente por outro aplicativo. Eles podem, no entanto, ser configurados para excluir dados em cache expirados regularmente.

Monica - Desculpe, acho que estou tendo um dia ruim. Você pode explicar isso um pouco mais?

João - Claro. Sempre que você passar um objeto para save , update , saveOrUpdate , ou recuperá-lo via load , get , list , iterate ou scroll , esse objeto será adicionado ao cache interno da sessão. Você também pode remover o objeto e suas coleções do cache de primeiro nível.

Mônica - É...

John - Além disso, você pode controlar os modos de cache. Você pode usar o modo normal para ler e gravar itens no cache de segundo nível. Use o modo get para ler a partir do segundo nível, mas você não pode escrever de volta. Use put , que é o mesmo que get , mas você não pode ler a partir do segundo nível. Você também pode usar o modo de refresh , que gravará no segundo nível, mas não lerá a partir dele e ignorará a propriedade use minimal puts , forçando uma atualização do cache de segundo nível para todos os itens lidos do banco de dados.

Mônica - Entendi. OK. Deixe-me pensar sobre isso. Ah, é tarde, preciso ir. Obrigado pelo seu tempo!

João - De nada!

Desistir da hibernação

2 semanas atrás

Monica - John, pensei que estávamos entrando em uma nova era de desenvolvimento de software. Achei que estávamos fazendo um salto de um ano-luz. Mas, depois de quatro anos, parece que ainda estamos lidando com os mesmos problemas, só que de um ângulo diferente. Eu tive que aprender arquitetura Hibernate , configuração, logging, estratégias de nomenclatura, tuplizers, resolvedores de nome de entidade, geradores de identificador aprimorados, otimização de gerador de identificador, subclasses de união, marcação XDoclet, associações bidirecionais com coleções indexadas, associações ternárias, idbag, misturando polimorfismo implícito com outros mapeamentos de herança, replicação de objetos entre dois datastores diferentes, objetos desanexados e versionamento automático, modos de liberação de conexão, interface de sessão sem estado, taxonomia de persistência de coleção, níveis de cache, busca lenta ou ansiosa e muito, muito mais. Mesmo com tudo o que sei, parece que falhamos muito. É um fiasco de software! Falha final! Desastre! Armagedom!

João - Espera! O que aconteceu?

Monica - Chegamos a um beco sem saída. O desempenho do nosso aplicativo é ridiculamente lento! Para obter um relatório, temos que esperar dois dias! Dois dias para realmente gerar um painel para um cliente. Isso significa que a cada dia temos que aumentar nossa cauda de cálculo, enquanto nosso painel fica cada vez mais desatualizado. Nosso especialista em DBA está trabalhando há dois meses para otimizar algumas consultas, enquanto nossa estrutura de banco de dados está uma bagunça completa. Há desenvolvedores que o apoiam, mas o problema é que o DBA está pensando em SQL, e os desenvolvedores estão gastando dias tentando traduzir isso em critérios desanexados ou formato HQL. Estamos tentando usar o SQL nativo o máximo possível, pois o desempenho é crucial no momento. De qualquer forma, não podemos fazer muito, pois o esquema do banco de dados parece estar errado. Parecia certo do ponto de vista orientado a objetos, mas parece ridículo do ponto de vista relacional. Estou me perguntando: como isso aconteceu? Os desenvolvedores estão nos dizendo que mudar a estrutura das entidades será um grande esforço, então não podemos arcar com isso. Lembro que no projeto anterior foi uma bagunça, mas nunca chegamos a um ponto tão crítico. Conseguimos escrever um aplicativo totalmente diferente para trabalhar com os dados. Agora, é arriscado modificar essas tabelas geradas, pois é muito difícil garantir que o modelo de entidade sempre se comporte corretamente. E essa nem é a pior parte! Para aumentar o desempenho, temos que resolver não apenas problemas de banco de dados, mas também problemas com toda a camada entre nosso banco de dados e o aplicativo. É esmagador! Temos esses novos caras, você sabe, consultores. Eles estão tentando extrair dados, colocá-los em algum outro armazenamento e, em seguida, realizar cálculos de fora. Está tudo demorando muito!

João - Não sei o que dizer.

Monica - Você vê João; Eu não quero te culpar. Eu escolhi o Hibernate para resolver todos esses problemas, mas agora aprendi que não é uma bala de prata. O estrago já foi feito e é irreversível. Na verdade, eu gostaria de te perguntar uma coisa: eu passei os últimos quatro anos da minha carreira lidando com coisas do Hibernate . Parece que não tenho futuro na minha empresa atual. Pode me ajudar?

Então, qual é a lição aprendida?

Hoje

John - Ei, Peter, deixe-me apresentar a Monica.

Pedro - Ei, Mônica! Estamos construindo nossa nova próxima grande coisa, você sabe. Vai ser enorme! Queremos ser como o Uber! Você sabe talvez como a persistência…

Monica - Não Hiberna !

Embrulhar

Monica é uma especialista em Hibernate . No entanto, o Hibernate neste caso foi uma decisão errada. No momento em que ela descobriu que sua solução se transformou em um problema maior do que o original, foi a maior ameaça para todo o projeto.

Os dados são o objetivo central do aplicativo e, gostemos ou não, afetam toda a arquitetura. Como aprendemos com a história, não use o Hibernate apenas porque seu aplicativo Java está usando um banco de dados ou por causa de prova social. Escolha uma solução que abrace a flexibilidade. Há muitas opções para wrappers JDBC robustos, como JdbcTemplate ou Fluent JDBC Wrapper. Alternativamente, existem outras soluções poderosas, como jOOQ.