Read in english: click here
Quando a gente vai criar um projeto novo de backend, uma api REST pra um banco relacional por exemplo, a primeira coisa que vem à cabeça é Hibernate. Mas por quê? Você já parou pra pensar em como de fato essa ferramenta deixa seu trabalho mais fácil (ou difícil)? Você considerou as exatas necessidades da sua arquitetura e pensou em um bom motivo pra incluir ou não a ferramenta?
Estou aqui pra apresentar o bom, o mau e o feio sobre o Hibernate (e ORMs em geral), como eles podem atravancar o seu projeto mais do que você imagina, e é claro apresentar uma excelente alternativa.
O Bom
Vamos encarar os fatos: escrever um CRUD em JDBC puro é muito sofrido. Quando o Hibernate surgiu, foi a luz no fim do túnel. Mesmo na sua primeira versão (lançada em meados de 2001), o mapeamento baseado em XML era mil vezes melhor que aquelas tranqueiras de EJB Entity Beans. Ele evoluiu, ganhou annotations, e rapidamente virou o padrão mais popularmente aceito pra qualquer aplicação Java.
Escrever um CRUD em Hibernate é bem rápido e relativamente simples. A complexidade só aumenta conforme os relacionamentos entre as suas tabelas no banco também ficam mais complexos. E isto nos leva ao próximo ponto:
O Mau
Vou resumir em uma só palavra: mapeamentos. Sim, você ganhou bastante tempo escrevendo seu CRUD com Hibernate em comparação a tê-lo escrito em JDBC. Mas você já parou pra contar quanto tempo você desperdiçou no Google e no Stack Overflow tentando entender porquê aquele maldito mapeamento que deveria ser tão simples não está funcionando? E não se orgulhe dos seus 15 anos de experiência com os quais você consegue praticamente mapear qualquer coisa, porque aquele desenvolvedor junior no seu time também está apanhando e perdendo o mesmo tanto de tempo que você já perdeu. Quando já passaram dois dias e você ainda não conseguiu fazer o mapeamento funcionar, você começa a querer poder fazer aquele bom e velho SQL e se safar com isso.
Na real, porque não? E isso nos leva ao pior de tudo:
O Feio
Native Queries. Não mente pra mim, dá até um frio na espinha, né não? Por quê diabos você vai querer escrever SQL nativo quando você já está usando uma ferramenta ORM extremamente moderna e poderosa? Essas "pestinhas" acabam com todo o propósito de se ter um ORM, sem deixar você trocar o banco da aplicação por exemplo, entre outras coisas.
Hibernate é só flores enquanto o projeto está na fase dos CRUDs. Mas quando chegam os relatórios, onde você tem que criar joins imensas de muitas tabelas, consultas cheias de subqueries, e etc e tal, aí as coisas começam a ficar complicadas. Primariamente por conta daqueles mapeamentos mal resolvidos. Não tem um único projeto com Hibernate que eu tenha visto em toda a minha carreira (já são 16 anos) que seja totalmente livre de queries nativas. Alguém, em algum ponto do projeto, não tinha o tempo nem o conhecimento pra fazer da forma correta, lançou um ás da manga e meteu-lhe uma native query pra poder entregar no prazo.
Outro ponto feio que ninguém gosta de falar envolve performance. Não, eu não estou dizendo que Hibernate é lento, mas quando o DBA vem correndo da mesa dele reclamando que uma certa consulta está degradando a performance do banco e precisa de tuning imediatamente, a gente só olha pra ele com cara de dó e fala: "cara, aqui é Hibernate, eu não controlo como as queries são criadas, não vai rolar tuning não". Aí ele vai e fala com o gerente dele, que por sua vez fala com o seu gerente, e olha lá: nasce mais uma native query.
É claro que tudo isso gira em torno de falta de conhecimento com relação aos mapeamentos. Infelizmente, esse não é um tópico simples e, ao menos na minha humilde opinião, a documentação não é muito clara. Ainda estou pra conhecer um desenvolvedor que consiga encher o peito pra dizer: "Eu consigo mapear com precisão qualquer relacionamento que aparecer". As coisas só pioram quando quem está criando as tabelas e quem está criando o código Java não são a mesma pessoa.
Vamos pensar um pouco então. Ganhei um bom tempo na parte do CRUD, perdi todo ele ou talvez mais nos relatórios, e perdi todo o propósito disso escrevendo várias native queries. Qual foi a vantagem no fim? Usar um ORM realmente foi bom? Mas, se não foi bom, então pra onde eu corro?
A Alternativa
Você conhece o Spring, certo? Provavelmente você até já está usando ele na sua aplicação. O Spring Boot é uma base excelente pra qualquer aplicação Java e traz consigo muitas funcionalidades interessantes. Mesmo se você não gosta do Boot, o próprio core do Spring e até mesmo o Spring MVC são parte integrante de muitas aplicações Java hoje. E se eu te dissesse que você não precisa de nada além disso pra conseguir trabalhar com SQL sem lançar mão de ORMs e sem precisar usar JDBC diretamente?
Vamos dar uma olhada na documentação do Spring Framework, Data Access, capítulo 3: Data Access with JDBC. Ele apresenta um conjuto de classes utilitárias que abstraem todo o trabalho árduo e te deixa apenas com o processamento dos dados propriamente ditos. Isso, se aliado à anotação @Transactional também do Spring, te dá uma abordagem muito próxima do que você já está acostumado com o Hibernate em termos de controle de transação automático, mas sem a bagunça dos mapeamentos e com acesso direto ao SQL.
De acordo com a própria documentação, você só vai ter que:
- Definir os parâmetros de conexão (uma vez apenas)
- Escrever as queries (selects, basicamente)
- Prover os parâmetros
- Processar os dados que retornam.
Você NÃO vai ter que:
- Abrir / fechar conexões com o banco
- Se preocupar com detalhes da execução
- Escrever um laço pra iterar nas linhas retornadas
- Comitar / fazer rollback das transações e tratar exceções
- Fechar recursos (close resources)
Uma das melhores classes aqui é o BeanPropertyRowMapper. Ele consegue automaticamente popular uma lista de POJOs dado que na query você dê sinônimos (aliases) às colunas com nomes idênticos aos dos atributos do pojo. Quase um mapeamento, mas não exige consistência. Pra inserts, updates e deletes, você sequer vai precisar escrever SQL; passar o nome da tabela e um Map com nome da coluna + valor é suficiente.
Eu não vou aqui escrever um tutorial pra esse pedacinho de mau caminho porque esse não é o intuito desse artigo. Aqui eu só quero mostrar que existem excelentes alternativas pra uma ferramenta que causou (ao menos pra mim) mais problemas do que aqueles que ela deveria solucionar. Já escrevi alguns sistemas usando essa abordagem e meu sentimento é que em todos eles, o desenvolvimento no que se refere ao acesso ao banco de dados foi muito mais suave do que usando Hibernate. Digo, se você já sabe que vai ter que escrever um monte de SQL de qualquer jeito, por quê já não começar assim e pular as dores de cabeça de ter que escrever aqueles mapeamentos, tudo enquanto mantendo o mesmo controle automático de transação?
Caso você queira já começar a brincar com essa parte do Spring, eu preparei aqui umas classes wrapper pra dar um impulso inicial:
Conclusão
Eu sou uma pessoa realista e eu escrevi esse artigo baseado na minha experiência pessoal em vários projetos com vários times diferentes, usando Hibernate. Eu considero a criação de mapeamentos mais difícil do que deveria ser, e também trabalho desnecessário quando você já sabe SQL muito bem. Se o seu projeto não tem uma seção de relatórios e/ou você se sente confortável com os mapeamentos do Hibernate, então ele é sua melhor escolha. De outra forma, eu fortemente recomendo que você procure alternativas. Dá pra achar coisa muito boa fora da "modinha".
Top comments (0)