Algum tempo atrás o Fabiano me perguntou qual implementação de persistência em Java eu julgava a melhor opção. Na época conversamos um pouco sobre isso e eu estava para escrever sobre o assunto faz tempo.
Essa semana falei novamente sobre o assunto numa thread do CEJUG e então vou finalmente expôr algumas opiniões por aqui.
Provavelmente a implementação de persistência que está mais “na moda” atualmente é a Java Persistence Architecture (JPA) ou frameworks independentes com a mesma proposta, como o Hibernate e o Toplink. Realmente a proposta desta tecnologia é excelente. Quem programa usando orientação a objetos de verdade sempre prefere manipular classes de domínio ricas, e não gosta muito de lidar com as diferenças de paradigma que existem entre este modelo e o modelo relacional de bancos de dados.
A JPA aparentemente é bem fácil de usar, colocando anotações para mapear as classes e atributos em tabelas e colunas do banco de dados e colocando algumas anotações para declarar os relacionamentos entre as entidades. O problema que eu vejo é que as anotações de JPA são um tanto confusas. Em algumas situações você vê uma quantidade razoável de opções, e não fica tão óbvia a forma que você tem que usar as anotações.
Além disso, o esforço de analisar o comportamento da JPA é muitas vezes considerável. Você não escreve as queries, mas precisa acompanhar muito bem as queries que estão sendo geradas, se está sendo feito JOIN ou múltiplas queries, etc. Esse tipo de coisa a JPA abstrai da gente, mas muitas vezes os comportamentos não são triviais, e o esforço de monitorar isso não é desprezível. Uma anotação mal colocada pode te trazer problemas graves de performance e alguns dias de análise para otimização.
Eu gosto bastante da idéia de frameworks de mapeamento objeto-relacional. Quem trabalha verdadeiramente com orientação a objetos sempre quer ter a comodidade de usar este paradigma na aplicação toda. Entretanto, essas opções que temos em Java são complexas e muitas vezes não trazem ganhos de produtividade comparando com alternativas como o Ibatis por exemplo.
A parte mais chata da persistência em Java é escrever o código JDBC de gravação de objetos no BD e recuperação dos mesmos. Aqueles tratamentos altamente repetitivos e trabalhosos de conversão de colunas do BD de diferentes tipos para seus atributos das classes. Eu odeio escrever esse tipo de código, e o Ibatis ajuda demais nesse sentido, sem introduzir complexidade.
Uma coisa positiva que eu vejo no Ibatis é que ele é bem simples de usar e muito óbvio e previsível. Você manipula as coisas com o paradigma relacional, que embora tenha seus defeitos é amplamente conhecido de todo mundo e fácil de manipular. Usamos a DSL que é provavelmente a mais bem-sucedida até hoje (SQL).
A implementação de mapeamento objeto-relacional do Django (framework Python) por exemplo é excepcional, extremamente inteligente e produtiva. Muito dificilmente trocaria ela pelo Ibatis (assumindo que trocar fosse uma opção). Mas já há algum tempo eu estou desiludido com a JPA e vejo o Ibatis como uma opção com melhor custo-benefício.
Em situações em que o time todo domina plenamente JPA e já têm uma boa experiência com a mesma, é possível que o time ganhe um pouco de produtividade ao usá-la. Entretanto, em muitas situações o custo-benefício pode ser pior do que usar o Ibatis.
Já presenciei alguns casos em que a adoção de JPA em diferentes equipes prejudicou mais do que ajudou. Os principais motivos para isso foram:
- Falta de experiência geral do time com a tecnologia
- Modelos legados de BD que não permitem um mapeamento de classes tão interessante
- Grande esforço de tunning
Eu e outros profissionais que eu respeito muito já passamos por esse tipo de situação, em que acabou prevalecendo o pragmatismo e a visão do que é valor para o negócio.
Eu li uma entrevista com o Carlos Ghosn (o brasileiro presidente da Renault e Nissan) na qual ele falou que a Nissan passou a ter bons resultados quando os engenheiros pararam de colocar ítens que eles achavam “bonitos” nos projetos, mas que os usuários nem percebiam. O argumento era mais ou menos esse: o usuário quer que o carro funcione bem, não importa para ele se o revestimento do motor vai ser de adamantium e resistente a criptonita
Decisões técnicas devem ser tomadas com foco no valor de negócio, em vez de focar na tecnologia que ficará mais bonita no currículo. Não esqueçam do exemplo do Carlos Ghosn
Excelente Bruno, só tive tempo de ler agora sua visão sobre o assunto, mas sempre é tempo. O que eu acho sobre isso é que para os modelos legados é tiro no pé querer colocar Hibernate/JPA. No caso de um projeto novo eu concordo contigo que vai do time conhecer ou não a ferramenta. Caso contrário, melhor usar o que todos saibam.