Falando como alguém que passou bastante tempo trabalhando com JPA (Java Persistence API, basicamente a API ORM padronizada para Java / J2EE / EJB), que inclui Hibernate, EclipseLink, Toplink, OpenJPA e outros, vou compartilhar alguns dos meus observações.
- ORMs não são rápidos. Eles podem ser adequados e, na maioria das vezes, adequados, mas em um ambiente de alto volume e baixa latência, eles são um não-não;
- Em linguagens de programação de propósito geral, como Java e C #, você precisa de muita magia para fazê-las funcionar (por exemplo, tecelagem de tempo de carregamento em Java, instrumentação etc.);
- Ao usar um ORM, em vez de se afastar do SQL (que parece ser a intenção), você ficará surpreso com quanto tempo gasta aprimorando XML e / ou anotações / atributos para fazer com que seu ORM gere SQL de desempenho;
- Para consultas complexas, realmente não há substituto. Como no JPA, existem algumas consultas que simplesmente não são possíveis no SQL bruto e, quando você precisa usar o SQL bruto no JPA, isso não é bom (C # /. Net pelo menos possui tipos dinâmicos - var - o que é muito melhor que uma matriz de objetos);
- Existem muitas "dicas" ao usar ORMs. Isso inclui comportamento não intencional ou inesperado, o fato de que você precisa desenvolver a capacidade de fazer atualizações SQL no seu banco de dados (usando refresh () no JPA ou métodos semelhantes, porque o JPA, por padrão, armazena em cache tudo, para não capturar um banco de dados direto atualização - executar atualizações diretas do SQL é uma atividade comum de suporte à produção);
- A incompatibilidade objeto-relacional sempre causará problemas. Com qualquer problema desse tipo, há uma troca entre complexidade e completude da abstração. Às vezes, senti que o JPA foi longe demais e atingi uma lei real de retornos decrescentes, onde a complexidade não era justificada pela abstração.
Há outro problema que requer um pouco mais de explicação.
O modelo tradicional de um aplicativo da Web é ter uma camada de persistência e uma camada de apresentação (possivelmente com serviços ou outras camadas intermediárias, mas essas são as duas importantes para esta discussão). Os ORMs forçam uma visão rígida da camada de persistência até a camada de apresentação (ou seja, suas entidades).
Uma das críticas de mais métodos SQL brutos é que você acaba com todos esses VOs (objetos de valor) ou DTOs (objetos de transferência de dados) que são usados por apenas uma consulta. Isso é apresentado como uma vantagem dos ORMs, porque você se livra disso.
O problema é que esses problemas não desaparecem com os ORMs, eles simplesmente passam para a camada de apresentação. Em vez de criar VOs / DTOs para consultas, você cria objetos de apresentação personalizados, geralmente um para cada exibição. Como isso é melhor? IMHO não é.
Eu escrevi sobre isso no ORM ou SQL: já chegamos? .
Minha tecnologia de persistência de escolha (em Java) atualmente é ibatis. É um invólucro bastante fino em torno do SQL que faz mais de 90% do que o JPA pode fazer (ele pode até carregar carregamentos preguiçosos de relacionamentos, embora não esteja bem documentado), mas com muito menos sobrecarga (em termos de complexidade e código real).
Isso surgiu no ano passado em um aplicativo GWT que eu estava escrevendo. Muita tradução do EclipseLink para objetos de apresentação na implementação do serviço. Se estivéssemos usando o ibatis, seria muito mais simples criar os objetos apropriados com o ibatis e passá-los para cima e para baixo na pilha. Alguns puristas podem argumentar que isso é Bad ™. Talvez sim (em teoria), mas eu lhe digo: isso levaria a um código mais simples, uma pilha mais simples e mais produtividade.