Hibernate, iBatis, Java EE ou outra ferramenta Java ORM

Estamos no processo de planejar um grande aplicativo corporativo. Estamos concentrando nossos esforços na avaliação do hibernate depois de experimentar as dores do J2EE.

Parece que a nova API do Java EE é mais simples. Eu também li algumas coisas boas sobre o Hibernate e o iBatis. Nossa equipe tem pouca experiência com qualquer um dos frameworks.

Existem 5 principais pontos de comparação que eu gostaria de determinar

  • Curva de Aprendizagem / Facilidade de Uso
  • Produtividade
  • Manutenção / Estabilidade
  • Desempenho / Escalabilidade
  • Facilidade de solução de problemas

Se você fosse gerenciar uma equipe de ~ 6 desenvolvedores com experiência em J2EE que ferramenta ORM você usaria e por quê?

Deixe-me dar uma olhada nisso. Primeiro de, eu escrevi alguns sobre este assunto em Usando um ORM ou SQL simples? . Especificamente para abordar seus pontos:

Curva de Aprendizagem / Facilidade de Uso

Ibatis é sobre SQL. Se você conhece SQL, a curva de aprendizado para ibatis é trivial. Ibatis faz algumas coisas sobre o SQL, como:

  • Agrupar por;
  • tipos discriminados; e
  • SQL dynamic.

que você ainda precisa aprender, mas o maior obstáculo é o SQL.

JPA (que inclui o Hibernate), por outro lado, tenta se distanciar da SQL e apresentar as coisas em um object em vez de um modo relacional. Como Joel aponta no entanto, as abstrações estão vazando e o JPA não é exceção. Para fazer o JPA, você ainda precisará saber sobre modelos relacionais, SQL, ajuste de desempenho de consultas e assim por diante.

Considerando que Ibatis simplesmente fará você aplicar o SQL que você conhece ou está aprendendo, o JPA exigirá que você saiba algo diferente: como configurá-lo (XML ou annotations). Com isso quero dizer que os relacionamentos de chave estrangeira são um relacionamento (um-para-um, um-para-muitos ou muitos-para-muitos) de algum tipo, o tipo de mapeamento, etc.

Se você souber SQL, eu diria que a barreira para aprender JPA é realmente maior. Se você não o fizer, será mais um resultado misto com o JPA, permitindo adiar o SQL de aprendizado por um tempo (mas não adia indefinidamente).

Com o JPA, uma vez que você configura suas entidades e seus relacionamentos, outros desenvolvedores podem simplesmente usá-los e não precisam aprender tudo sobre a configuração do JPA. Isso pode ser uma vantagem, mas um desenvolvedor ainda precisará saber sobre gerenciadores de entidades, gerenciamento de transactions, objects gerenciados versus não gerenciados e assim por diante.

Vale a pena notar que o JPA também possui sua própria linguagem de consulta (JPA-SQL), a qual você precisará aprender se conhece SQL ou não. Você encontrará situações em que o JPA-SQL simplesmente não pode fazer coisas que o SQL pode fazer.

Produtividade

Isso é difícil de julgar. Pessoalmente, acho que sou mais produtivo em ibatis, mas também me sinto muito confortável com o SQL. Alguns argumentam que são muito mais produtivos com o Hibernate, mas isso é possivelmente devido – pelo menos em parte – ao desconhecimento do SQL.

Além disso, a produtividade com JPA é enganosa porque você ocasionalmente se deparará com um problema com seu modelo de dados ou consultas que levará metade de um dia a um dia para resolver ao ativar o registro e observar qual SQL seu provedor JPA está produzindo e funcionando a combinação de configurações e chamadas para fazê-lo produzir algo que seja correto e de alto desempenho.

Você simplesmente não tem esse tipo de problema com Ibatis porque você mesmo escreveu o SQL. Você o testa executando o SQL dentro do PL / SQL Developer, do SQL Server Management Studio, do Navicat for MySQL ou qualquer outra coisa. Depois que a consulta estiver correta, tudo o que você está fazendo é mapear inputs e saídas.

Também achei o JPA-QL mais complicado do que o SQL puro. Você precisa de ferramentas separadas para apenas executar uma consulta JPA-QL para ver os resultados e é algo mais que você precisa aprender. Eu realmente encontrei toda essa parte do JPA bastante desajeitada e difícil de lidar, embora algumas pessoas gostem.

Manutenção / Estabilidade

O perigo com Ibatis aqui é proliferação, o que significa que seu time de desenvolvimento pode continuar adicionando objects de valor e consultas conforme necessário, ao invés de procurar por reutilização, enquanto o JPA tem um direito por tabela e uma vez que você tem aquela entidade, é isso. Consultas nomeadas tendem a entrar nessa entidade, por isso são difíceis de perder. Consultas ad-hoc ainda podem ser repetidas, mas acho que é um problema menor.

Isso vem com o custo de rigidez no entanto. Muitas vezes, em um aplicativo, você precisará de bits e pedaços de dados de diferentes tabelas. Com o SQL é fácil, porque você pode escrever uma única consulta (ou um pequeno número de consultas) para obter todos os dados em um hit e colocá-lo em um object de valor personalizado apenas para esse fim.

Com o JPA, você está migrando essa lógica para a sua camada de negócios. Entidades são basicamente tudo ou nada. Agora isso não é estritamente verdadeiro. Vários provedores JPA permitem que você carregue parcialmente entidades e assim por diante, mas mesmo assim você está falando sobre os mesmos direitos discretos. Se você precisar de dados de 4 tabelas, precisará de 4 entidades ou precisará combinar os dados desejados em algum tipo de object de valor personalizado na camada de negócios ou de apresentação.

Uma outra coisa que eu gosto sobre o ibatis é que todo seu SQL é externo (em arquivos XML). Alguns vão citar isso é uma desvantagem, mas não eu. Você pode então encontrar usos de uma tabela e / ou coluna relativamente fácil, pesquisando seus arquivos XML. Com o SQL embutido no código (ou onde não há SQL), pode ser muito mais difícil de encontrar. Você também pode recortar e colar SQL em uma ferramenta de database e executá-lo. Eu não posso exagerar o suficiente quantas vezes isso tem sido útil para mim ao longo dos anos.

Desempenho / Escalabilidade

Aqui eu acho que ibatis vence as mãos para baixo. É direto do SQL e de baixo custo. Por sua natureza, o JPA simplesmente não conseguirá gerenciar o mesmo nível de latência ou taxa de transferência. Agora, o que a JPA tem a fazer é que a latência e o rendimento raramente são problemas. Sistemas de alto desempenho, no entanto, existem e tenderão a desfavorecer soluções mais pesadas, como o JPA.

Além disso, com ibatis você pode escrever uma consulta que retorna exatamente os dados desejados com as colunas exatas de que você precisa. Fundamentalmente, não há como o JPA conseguir vencer (ou até mesmo corresponder) quando estiver retornando entidades distintas.

Facilidade de solução de problemas

Eu acho que esta é uma vitória para Ibatis também. Como eu mencionei acima, com o JPA você gastará meio dia fazendo uma consulta ou entidade produzir o SQL que você quer ou diagnosticando um problema onde uma transação falha porque o gerenciador de entidade tentou persistir um object não gerenciado (que poderia ser parte de um lote). trabalho em que você cometeu muito trabalho, por isso pode não ser trivial encontrar).

Ambos falharão se você tentar usar uma tabela ou coluna que não existe, o que é bom.

Outros critérios

Agora você não mencionou a portabilidade como um dos seus requisitos (o que significa mover-se entre os fornecedores de database). Vale a pena notar que aqui a JPA tem a vantagem. As annotations são menos portáteis do que, digamos, o Hibernate XML (por exemplo, as annotations JPA padrão não têm um equivalente para o tipo de ID “nativo” do Hibernate), mas ambas são mais portáveis ​​que ibatis / SQL.

Também vi o JPA / Hibernate usado como uma forma de DDL portátil, o que significa que você executa um pequeno programa Java que cria o esquema do database a partir da configuração do JPA. Com o ibatis, você precisará de um script para cada database suportado.

A desvantagem da portabilidade é que o JPA é, em alguns aspectos, o menor denominador comum, o que significa que o comportamento suportado é, em grande parte, o comportamento comum suportado por uma ampla gama de fornecedores de database. Se você quiser usar o Oracle Analytics no ibatis, não há problema. Na APP? Bem, isso é um problema.

Uma regra prática simplista entre o iBatis e o Hibernate é que, se você quiser mais visão SQL / relacional do mundo, o iBatis é mais adequado; e para cadeia de inheritance mais complexa, e menos visão direta para SQL, Hibernate. Ambos são amplamente utilizados e sólidos bons frameworks. Então, acho que ambos provavelmente funcionariam bem. Talvez leia um tutorial para ambos, veja se um soa melhor que o outro, e apenas escolha um.

Das coisas que você lista, eu não acho que o desempenho é muito diferente – o gargalo será quase invariavelmente o database, não o framework. Para outras coisas, acho que desenvolvedores diferentes prefeririam um ou outro, ou seja, não há uma prioridade comumente aceita (para iBatis vs Hibernate).

Com qual solução você está, depende também da conformidade que você escolhe (ou é necessário) para estar com a especificação Java EE. O JPA é “o padrão” para o access a dados em sistemas Java EE, portanto, se você aderir a isso, deverá usá-lo (com algumas ressalvas).

JPA é uma padronização de sistemas de mapeamento relacional de object. Como tal, não fornece uma implementação, simplesmente define uma abordagem padronizada. O Hibernate Entity Manager é uma dessas implementações.

Como o JPA é um padrão entre vários fornecedores e ainda é relativamente novo, ele não possui uma funcionalidade mais esotérica que é valiosa em alguns casos de uso (por exemplo, uma API Criteria para gerar SQL dynamic). Se você for com o plano JPA em situações onde você precisará usar o Hibernate diretamente, ou mesmo o JDBC diretamente. Para situações como essa, um padrão DAO genérico é muito útil; você pode modificar este: Generic Data Access Objects para uso em JPA e JDBC com bastante facilidade.

O JPA tem algumas restrições difíceis (particularmente se você está acostumado com o Hibernate), e impõe certas abordagens em você que são difíceis para desenvolvedores que estão mais acostumados a escrever JDBC direto. Se você está defendendo isso como uma abordagem, certifique-se de fazer sua lição de casa sobre os prós e contras de ORM x JDBC.

Se você for com o JPA, uma vez que tenha atingido a curva de aprendizado, ele será recompensado em termos de desenvolvimento simples (particularmente se você implementar adequadamente o padrão DAO mencionado anteriormente), mas também em obter armazenamento em cache de vários níveis dos resultados da consulta. Se feito corretamente (um grande “se”, eu sei), eu vi isso fornecer benefícios consideráveis.

Por fim, se você tiver um modelo de dados legado com pouco flexibilidade, o Hibernate (e o JPA) lhe dará mais dores de cabeça do que talvez valha a pena. Por exemplo:

  • Se o database não tiver chaves primárias candidatas (para implementações hashCode efetivas e iguais), será necessário fazer uma análise inicial sobre quais colunas definem uma única linha – talvez simples, talvez complexo, dependendo da complexidade de seu esquema;
  • Se você não conseguir adicionar colunas de versão ou timestamp, você perderá a capacidade do Hibernate de fazer um bloqueio otimista e acabará tendo que consultar antes de atualizar.

(Adicionado em resposta ao primeiro comentário) Se você tiver sorte o suficiente para redesenhar seu database, duas considerações muito importantes se você estiver usando um ORM:

  • Adicione uma coluna de número de versão a todas as tabelas relevantes para suportar o bloqueio otimista.
  • Durante sua análise de dados, decida sobre colunas ” chave alternativa ” não anuláveis ​​que os desenvolvedores devem usar para hashCode() & equals() . Não use colunas PK nesses methods.

Para adicionar outra opção à lista … dê uma olhada em:

Ebean ORM ( http://ebean-orm.github.io ).

Sua principal reivindicação seria um modelo de programação mais simples e intuitivo do que o JPA ou o Hibernate. Especificamente, ele não possui uma Session do Hibernate ou EntityManager do JPA, nenhum object separado / anexado (sem mesclagem, persistência, flush), o carregamento lento simplesmente funciona.

… também muito mais simples de usar e entender.

Você também pode usar seu próprio SQL com o Ebean (para consultas, atualizações, stored procedures) e o IMO combina com o Ibatis na facilidade de uso usando seu próprio SQL.

Se você estiver olhando para usar o ORM em Java SE, então eu sugiro que você verifique isso.

  • Licença LGPL
  • Use annotations JPA para mapeamento (@Entity, @OneToMany etc)
  • API sem session (sem mesclagem, persist, flush … save () e delete ())
  • Suporte “Objeto parcial”
  • Suporte à Consulta Grande (por contexto de persistência do gráfico de object)
  • Consultas em segundo plano
  • Bom suporte para processamento em lote
  • Ajuste automático de consultas (via “Autofetch”)

Felicidades, Rob.

Atualmente estamos trabalhando em um projeto que usa tanto o Hibernate quanto o ibatis. Por que usar o modo de hibernação? Ele suporta nosso modelo de domínio, relacionamentos e inheritance. Nós temos um modelo de domínio bastante complexo e o hiberante o suporta muito bem. Não precisa se preocupar em escrever inserções, atualizações etc. Ibatis é usado apenas para exibição. Há consultas e temos objects de visualização (semelhantes a modelos de domínio, mas não a modelos de domínio) que são mapeados com consultas. Ibatis retorna os dados no object de exibição que você deseja, sem se preocupar com a leitura do conjunto de resultados, que você deve gerenciar no Spring JDBC. Por que nós, em vez de usar o HQl ou o Spring JDBC? O domínio é tão complexo e, ao renderizar a visualização, fazemos cálculos, agrupamos por e toneladas de funções SQL nativas. Fazemos tudo isso em consultas, usamos consultas dinâmicas, gerenciamos condições no ibatis e obtemos um object de peso leve. Faz muito mais sentido se você tiver que percorrer várias camadas para buscar dados no modo de hibernação. Então, dependendo da sua situação, você pode querer usar apenas um, ambos ou pode não ser nenhum. Mas definitivamente, a hibernação não é algo que você não pode viver sem.

Esteja ciente de que o uso de JPA / Hibernate (e provavelmente a maioria das soluções ORM) em aplicativos multi-thread não triviais pode rapidamente se tornar um PITA real, porque sessões de database precisam ser confinadas em exatamente um thread (objects Session não são thread-safe). Adicione o carregamento lento e o fato de que entidades persistentes podem pertencer a no máximo uma session ativa … e você terá uma viagem incrível …

Você pode querer dar uma olhada no gerenciamento de sessões usando o Hibernate em um aplicativo * multi-threaded * Swing (ou apenas procure por ‘multi-threaded’ hibernate).

Minha regra de ouro (YMMV): Se o aplicativo não se presta a algum tipo de ciclo de solicitação / resposta (como um serviço da Web, por exemplo), provavelmente será melhor usar outra coisa.

Naturalmente, outra solução seria projetar o aplicativo de uma maneira que contorna as limitações do framework mencionado. Alterar o design de um aplicativo para que eu possa fazer com que o framework XYZ funcione deixa um sabor ruim.

De qualquer forma, apenas meu $ 0,02

Eu acho que devemos levar em consideração a principal razão pela qual estamos usando Java (ou OO).

O sistema tem que ser flexível e permitir modificações constantes na especificação (isso acontece com muita frequência na vida real). Caso contrário, deveríamos ter programado em C, porque é muito mais rápido.

Eu acho que a melhor pilha para aplicativos da Web seria Java EE: JPA – EJB – JSF (com escopo de conversação de contexto de persistência estendida).

O JSF também é mais lento que o JSP / Servlet puro, mas é mais rápido de desenvolver.

O JPA é mais difícil de aprender, mas é mais rápido desenvolver (você sabe: RAD) e as mudanças não têm grande impacto (copiar e colar) propenso a erros. Adicione uma nova coluna na sua entidade mais usada, e você terá que atualizar todas as declarações no iBatis …

O JPA não funciona muito bem em todos os casos, mas abrange a maioria deles e também permite que você conecte o Native Query em vez do JPQL sem alterar nenhum código. Mas se você estiver escrevendo muito Native Query, seu projeto pode se encheckboxr melhor no iBatis.

E quanto ao desempenho, o JPA também tem desempenho se você entender como as coisas são traduzidas para o SQL, e se você colocá-lo para fazer o que ele é melhor, se você fizer algo que não seja confortável para ele, ele gerará muitas consultas . Não há mágica! Você tem que estar ciente da consulta gerada, e não esperar cegamente que você pode pegar o caminho mais fácil quando algum caso complicado pode aparecer.

Além disso, se os desenvolvedores tiverem todos os resources do SQL, eles escreverão consultas muito complexas para processar a lógica de negócios, em vez de tê-la em um local centralizado, você terá alguma lógica de negócios no SQL, algumas no EJB. O JPA deve ser para persistir seu modelo, não para a Business Logic.

A consulta de critérios também não é páreo para criar consultas dinâmicas complexas nomatterhowcomplex.

Se você realmente tem um projeto greenfield, você pode usar o modo de hibernação, mas esteja ciente de que a curva de aprendizado é bastante íngreme.

Se você tem um database existente, você é muito melhor com o iBatis, porque depois de um dia você é produtivo e depois de mais dois dias você pode saber tudo sobre ele.

Uma coisa que você deve considerar é que a API de critérios de hibernação é excelente para criar consultas personalizadas, o que, dependendo da sua aplicação, pode ser um bom argumento para isso.

Se você não tem um bom modelo de object, não vejo o benefício do Hibernate. Você certamente tem o “relacional” no ORM, já que você tem um database relacional, mas o “object” é a chave. Nenhum object, nenhum ORM. Eu acho que um mapeamento 1: 1 entre objects e tabelas, sem um comportamento de object mais rico, não justifica o ORM. Ficar com JDBC ou iBatis se essa é a sua situação.

Eu sugeriria ir com o JPA e depender (pesadamente!) Da duração / escopo do seu projeto, você poderia também olhar para o JPA2, pois ele fornece alguns dos resources ausentes do JPA (uma API de Consulta muito interessante, por exemplo).

Vá com o modo de hibernação. Seu projeto definitivamente crescerá mais tarde e o investimento (na aprendizagem de hibernação) será compensado de uma maneira ou de outra.

Você já tentou responder POR QUE até mesmo usar uma ferramenta ORM antes de decidir qual deles usar? Se você tem pessoas em sua equipe que conhecem SQL, consulte Furar ao JDBC.