Qual a importancia de se utilizar JPA ao invés de Hibernate?

[quote=rogelgarcia]
Pois então… tudo isso que voce falou aí … chegou atrasado… já existem essas features a 5 anos no framework que eu criei :smiley:

Pros projetos que eu uso então… nao teria vantagem… a nao ser a questao de portabilidade que é o menos importante…

E se eu quiser usar o JPA no desktop… é trivial?[/quote]

Então seu framework chegou atrasado, estas features já existiam a muito mais tempo na integração do Spring com HIbernate, por exemplo. Mas sua pergunta não foi essa, e sim - “Qual a importancia de se utilizar JPA ao invés de Hibernate?” - não somado a utilização de outros framework.

Utilizar JPA em Desktop tem os mesmos problemas de utilizar Hibernate em Desktop. Com a vantagem de você poder utilizar o Persistence.createEntityManagerFactory(“blablabla”) em vez de implementar o HibernateUtil.

Embora discorde dos pontos que vc colocou, Taborda, como justificativa a NUNCA usar JPA, eu respeito. Faço isso por conhecer e ter trabalhado com pessoas que tem a mesma visão que a sua. Na minha opinião é uma decisão de arquitetura, tem gente que gosta, tem gente que não.

Mas gostaria realmente de enteder alguns destes pontos que vc colocou. Por exemplo:

[quote=sergiotaborda]O JPA nasceu como uma alternativa OO ao JDBC mas ao contrario deste ele nasceu falho. O conceito de Native Query é completamente idiota
porque mata o objetivo de ter um mecanismo portável entre bancos. Da mesma forma que o JDBC precisa de um mecanismo para o adquar a vários bancos o JPA precisa do mesmo. O Hibernate não precisa.[/quote]

Pq nasceu falho e o que isso tem haver com nativeQuery? Na verdade o próprio Hibernate tbm tem suporte a queries nativas através de session.createSQLQuery, exatamente da mesma forma que entityManager.nativeQuery. Assim como no hibernate, utiliza querys nativas quem quer por própria conta e risco, ou pode usar JPQL ou Criteria com a APi da especificação, como vc usa HQL com o HIbernate Core.

[quote=Lavieri][quote=mario.fts]Lavieri

poderia explicar melhor esta estrutura:

pelo que eu entendi queries é uma classe onde vc pode pegar objetos de consulta especificos de cada classe do mdoelo, no caso o forPessoa retorna um desses objetos pra classe Pessoa. nesses objetos estão as queries especificas de pessoas, como no exemplo listPessoasAtivas. só não entendi o que esse query on retorna, acho que é um obejto que sabe qual query a ser executada no repositório, mas não estou com certeza disso.

Achei muito bacana, quero entender pra montar algo do tipo.

[]'s[/quote]

queries e’ uma fachada… ele conhece os caminhso para os objetos que conhece a query de cada entidade…

public class Queries { public PessoaQuery forPessoa() { return PessoaQuery.getInstance(); } public ImovelQuery forImovel() { return ImovelQuery.getInstance(); } } //ou seja apenas uma facahada.....

PessoaQuery contem todas as querys para pessoas

[code]
public class PessoaQuery {
public QueryableList listarAtivas() {
DatechedCriteria dc = DatechedCriteria.forClass(Pessoa.class)
.add(Restrictions.eq(“ativo”,true);
return new HibernateQuery(dc).list();
}

 public Queryable<Pessoa> byCpf(String cpf) {
       //...
       return new HibernateQuery<Pessoa>(dc).unique();
 }

}[/code]

QueryableList e’ uma interface

[code]

public Queryable {
T queryOn(Repository rep);
}

public QueryableList extends Queryable<List> {
List queryOn(Repository rep,int startPosition);
List queryOn(Repository rep,int startPosition,int maxResults);
}[/code]

HiberanteQuery e’ uma classe que retorna Queryable ou QueryableList

public HiberanteQuery<T> { public HiberanteQuery<T>(DetachedCriteria dc) {this.dc = dc} Queryable<T> unique(); Queryable<T> first(); Queryable<Integer> count(); QueryableList<T> list(); }

a implementacao desses metados e’ juntar a session do Repository com a DatechedCriteria que e’ passado no construtor.

e assim retorna a consulta tipada que esta definida no queryable ou queryablelist[/quote]

Quanta complicação. :shock: Qual o objetivo disto tudo?
Crie um Repository (Interface sobre uma DAO ou como uma classe Concreta) e seja feliz!

eu sou feliz, vc nao ?

o objetivo e’ tornar o codigo claro, legivel, e separar a camada de persistencia do restante do projeto.

nao pense que fico la escrevendo o queries o tempo todo, e que la tem consultas q eu nao preciso por exemplo…

o processo e’ simples

queries.forPessoas().[color=red]listPessoasAtivas()[/color]

nesse ponto eu aperto CTRL + 1 … no eclipse, ele cria o metodo na classe, eu escrevo o DetachedCriteria rapidinho e pronto, volto pra logica

depois sempre que precisa fica la no mesmo canto a consulta…

eu trabalho em varios projetos ao mesmo tempo, todos com o mesmo pacote basico, e com a mesma estrutura … trabalhar em um com centanas de dao, pode ser bom, mas quando trabalhe com varios e’ so ter 2 objetos para camada de persistencia (o Repositorio e o Queries) e’ simplismente otimo

um lugar onde se guardam e retornam objetos de qualquer tipo é um DomainStore. É por isso que vc consegue criar uma implementação baseada no Hibernate porque ele tb é um DomainStore. Vc está simplesmente desacoplando o conceito da implementação. Mas ao trocar o nome do conceito vc está fazendo um mal a si mesmo.

O repositório é um objeto que cria criterios e os envia ao DomainStore para serem executados.
No seu caso, vc tem uma classe com métodos estáticos que lhe dão a query que precisa e executa em cima do domainStore ( o que vc chama de reposiotorio é na realidade um DomainStore).

A sua arquitetura não tem Repositorios.

Vc não tem 10928239289 repositorios mas tem 10928239289 métodos estáticos numa classe. Qual vc acha que é melhor prática ?
Um consulta rápida na internet lhe mostrará que coisas estáticas são evil. A principal razão é que não são testáveis (porque não são “mokáveis”).
Aposto que vc não tem testes para essa classe.

Errado. Primeiro as queries fazem parte da camada de dominio. É um erro comum achar que fazem parte da persistencia, mas não fazem. Elas mudam conforme as regras do dominio e conforme a organização do dominio, logo são da camada de dominio.
Segundo, tudo bem que desassocie as consultas do local onde os objetos estão (DomainStore) , mas o problema aqui é a criação e controle dessas queries, não as queries em si, nem o DomainStore. E é ai que entra o padrão Repository

Não é uma questão de ser legal ou não. É uma questão de ser flexivel, desacoplado, de facil manutenção e testável.

Calma que eu não disse que vc não era feliz, apenas usei uma expressão. Nem te conheço, como posso dizer uma coisas destas. :slight_smile:

Eu que eu acho é que a abstração da persistência que o Hibernate, por exemplo, fornece é mais que o suficiente.
Então porque não usar uma classe Repository apenas e implementar a buscas usando o Hibernate diretamente.

Senão eu tenho a impressão se estar usando a abstração da abstração da abstração da …
E ter um repositório de queries, da maneira proposta, não me parece promover o reuso.

hmmm, 10928239289 métodos estáticos

vc tem certeza que leu parte do codigo que coloquei aqui ?? te desafio a achar 1 metodo estatico sequere, fora o padrao singleton, que vc mesmo sabe que e’ boa pratica.

Nao ha metodos estaticos, nao ha necessidade deles, meus objetos sao concretos,

O que tenho e uma fachada, o que e’ outro padrao.

public class Queries { public PessoaQuery forPessoa() { return PessoaQuery.getInstance(); } }

Queries e’ uma fachada, serve apenas como concentrador para os varios objetos do tipo Query, como o PessoaQuery.

esses objetos sao singleton, pq nao vejo necessidade de instanciar mais de 1.

Queries seria o mesmo que uma fabrica de PessoaQuery, mas como PessoaQuery e’ um singleton, ele nao pode ser conciderado fabrica.

Quanto ao nome, como disse, o nome pode ser outro, mas o q me atenho aqui sao ha boas praticas…

e gostaria que me disesse onde esta a ma pratica ? e pq eu deveria usar

new PessoaQuery (ou new RepositoryPessoa)
new OutroQuery (ou new RepositoryOutro)
??

quando posso fazer “queries.” e deichar o eclipse me trazer um atalho para a lista com todos os objetos desta categoria ?

nao gosta de fachadas ? paciencia, prefere ter q saber o caminho e o nome de cada Repository ou Query, parabens pra vc, eu prefiro nao ter q me preucupar com isso

Haa e seguindo o padrao fachada… o acesso aos PessoaQuery sao livres, e vc pode nao utilizar o Queries (que e’ apenas o concentrador) e utilizar outro caminho para chegar la

[quote=Alexandro.Almeida]Calma que eu não disse que vc não era feliz, apenas usei uma expressão. Nem te conheço, como posso dizer uma coisas destas. :slight_smile:

Eu que eu acho é que a abstração da persistência que o Hibernate, por exemplo, fornece é mais que o suficiente.
Então porque não usar uma classe Repository apenas e implementar a buscas usando o Hibernate diretamente.

Senão eu tenho a impressão se estar usando a abstração da abstração da abstração da …
E ter um repositório de queries, da maneira proposta, não me parece promover o reuso.

[/quote]

O Repositorio e’ reusavel sim… tenho ele sem mudar 1 linha em mais de 10 projetos…

Os objetos utilitarios como HiberanteQuery, as interfaces, Queryable, QueryableList, sao todas reutilizaveis… e tambem os tenho em mais de 10 projetos

A unica parte que nao e’ reutilizavel e’ o EntidadeXQuery obviamente, pois ele guarda a consulta de cada dominio,
e tb ele he trabalho nenhum de fazer, e ele nada mais faz q uma consulta ao hiberante normal, fazendo um DetachedCriteria, e retornando um HibernateQuery(dc).list() por exemplo…

O pacote esta pronto, o reuso e’ grande sim.

e so tenho q criar uma DetachedCriteria, e encapsultar em um HibernateQuery

[quote=sergiotaborda]

Errado. Primeiro as queries fazem parte da camada de dominio. É um erro comum achar que fazem parte da persistencia, mas não fazem. Elas mudam conforme as regras do dominio e conforme a organização do dominio, logo são da camada de dominio.
Segundo, tudo bem que desassocie as consultas do local onde os objetos estão (DomainStore) , mas o problema aqui é a criação e controle dessas queries, não as queries em si, nem o DomainStore. E é ai que entra o padrão Repository

Não é uma questão de ser legal ou não. É uma questão de ser flexivel, desacoplado, de facil manutenção e testável. [/quote]

ou eu me expressei mau, ou vc nao entedeu, mas vou explicar novamente…

o que quis dizer e’ que os objetos auxiliares para montagem das consultas, sao parte da camada de persistencia, e por isso eles sao bem definidos e separados do projeto.

Os EntidadeXQuery, realmente sao da camada de dominio, e de persistencia ao mesmo tempo, eles ficam no lemiar, eles fazem realmente limite com as duas camadas.

sua interface externa e’ para camada de dominio, porem sua implementacao usa a camada de persistencia.

JPA = Java Persistance API. Você só persiste em banco de dados ?
Supondo que sim, o JPA abstrai a sintaxe nativa do banco ? Não. Ele usa um sub conjunto da SQL que pertende ser universal,mas todos sabemos que isso é furada. é por isso que precisa das nativeQuery. Vc manda o encasuplamento (não era suposto vc saber que está usando um banco) e a portabilidade ( não era suposto saber qual banco usa). Isso é pior que JDBC. Pelo menos em JDBC eu posso criar DAOs para os diferentes bancos.

O problema não é se tem nativeQuery, o problema é o não encapsulamento. O Hibernate é um produto para banco de dados. É um ORM.
A JPA não tem que ser um ORM, mas ela está limitada a ser. Conceitos como Join poderiam ser mais agnosticos, mas eles são desenhados com banco de dados em mente.

A JPA é tecnicamente mais limitada que o Hibernate. Ambos têm o mesmo alvo: banco de dados.
Então a unica coisa que faria usar o JPA seria uma independencia maior (que ele não tem) tanto em termos de modelagem, como em termos de execução. Por exemplo, se o JPA não fosse apenas para banco de dados, valeria a pena. Ou se ele fosse realmente agnóstico. Caso contrário o hibernate já provê as mesmas funcionalidades.

Por outro lado o JPA não faz parte do JEE, logo, vc é tão livre de o escolher como escolher o hibernate ou outro qq ORM.

[quote=Lavieri][quote=sergiotaborda]

um lugar onde se guardam e retornam objetos de qualquer tipo é um DomainStore. É por isso que vc consegue criar uma implementação baseada no Hibernate porque ele tb é um DomainStore. Vc está simplesmente desacoplando o conceito da implementação. Mas ao trocar o nome do conceito vc está fazendo um mal a si mesmo.

O repositório é um objeto que cria criterios e os envia ao DomainStore para serem executados.
No seu caso, vc tem uma classe com métodos estáticos que lhe dão a query que precisa e executa em cima do domainStore ( o que vc chama de reposiotorio é na realidade um DomainStore).

A sua arquitetura não tem Repositorios.

Vc não tem 10928239289 repositorios mas tem 10928239289 métodos estáticos numa classe. Qual vc acha que é melhor prática ?
Um consulta rápida na internet lhe mostrará que coisas estáticas são evil. A principal razão é que não são testáveis (porque não são “mokáveis”).
Aposto que vc não tem testes para essa classe.
[/quote]

hmmm, 10928239289 métodos estáticos

vc tem certeza que leu parte do codigo que coloquei aqui ?? te desafio a achar 1 metodo estatico sequere, fora o padrao singleton, que vc mesmo sabe que e’ boa pratica.
[/quote]

Não. Vc está assumindo coisas que eu nunca disse.
O padrão não pode ser boa prática ou má prática.O uso dele é que pode. Quando vc usa Singleton em java.lang.Runtime é boa prática.
Quando vc usa nos seus XXXQuery é má prática.

Get your patterns straight.
Queries não é uma fachada. É um ServiceLocator

Pois. Esse é um erro comum.
Singleton não é usado para quando vc não quer mais que 1. É para quando vc não pode mais que 1.

veja

[code]
public class Queries {
private PessoaQuery pessoaQuery = new PessoaQuery();

 public PessoaQuery forPessoa() {
      return pessoaQuery;
 }

}[/code]

Estou usando singelton ?
Não.

Estou instanciando mais que um ?
Não.

Agora que vc explicou melhor, realmente os seus XXXQuery não na realidade repositorios.E é boa prática chamar as coisas com os nomes certos :slight_smile:

Eu não gosto é de ServiceLocator , nem de métodos estáticos, nem de outras coisas que impedem a felxibilidade e testabilidade.
Vc não precisaria do ".queryOn(repository); " se cada objeto XXXQuery tivesse uma referencia a ele. E isso é facil se eles não forem singleton.
E dessa forma vc consegue estar seu dominio com um domainstore em memoria sem usar banco. Muito mais rápido.
Flexibilidade. Testabilidade.

[quote]
Haa e seguindo o padrao fachada… o acesso aos PessoaQuery sao livres, e vc pode nao utilizar o Queries (que e’ apenas o concentrador) e utilizar outro caminho para chegar la[/quote]

Vamos pensar que uso o seu Queries. eu tenho que o injetar em todas as actions, mesmo quando sei que cada action só manipula uma certa entidade.
Obviamente eu não vou fazer “new Queres ()” dentro de cada action. eu voi injetar esse objeto.
Portanto, injetar isso ou injetar o próprio XXXQuery , qual é a diferença ? Pelos menos agora eu injeto apenas os XXQuery que preciso e não um God Locator

Enfim, o seu esquema é muito melhor do que é comum por ai. Estou apenas dizendo que poderia ser ainda melhor.

o Queries e’ application scoped, ou seja, injeto ele sem problemas so existe 1 no projeto…

eu quase nunca uso o queryOn(repository) … tem um outro metodo query() … so que esse metodo query() apesar de nao precisar do argumento
ele pega o repositorio de uma maneira q so pode ser feita em um app web, ou em um ambiente com threads no mesmo estilo do container web.

pois eu tenho um Interceptador, que guarda a referencia ao repositorio em um ThreadLocal, e resgato ele de la, pois sei, que uma requisicao esta sempre na mesma thread.

nesse ponto eu consigo fazer

List<Pesso> pessoas = queries.forPessoa().listAtivos();

sem usar o queryOn() …

injetar o queries
new Queries(repo).forPessoa().listAtivos();

ou fazer, queries.forPessoas().listaAtivos().queryOn(repo), pra mim tem o mesmo efeito… e eu axo mais bonito a segunda forma, e mais usavel no meu codigo.

vc fala em injetar o Repo dentro do XQuery, para poder usar em testes… mas isso seria o mesmo que nao injetar ele, e usar o metodo queryOn(repo)

Eu realmente nao quero mais de 1 instancia, pelo simples fato de nao precisar de mais de 1, por isso fiz o singleton, o construtor do XQuery e’ privado, portanto nao ha’ como criar ele por ai.

se fosse requerer o repository em sua construcao iria realmente ter q repensar o modelo, e tranformar o Queries em uma fabrica e nao deixar como esta.

Queries.createPessoa(repository).listAtivos();

então se o jpa não fosse jpa vc usaria ele? hahhhahahaha

[quote=bobmoe][quote=sergiotaborda]
A JPA é tecnicamente mais limitada que o Hibernate. Ambos têm o mesmo alvo: banco de dados.
Então a unica coisa que faria usar o JPA seria uma independencia maior (que ele não tem) tanto em termos de modelagem, como em termos de execução. Por exemplo, se o JPA não fosse apenas para banco de dados, valeria a pena. Ou se ele fosse realmente agnóstico. Caso contrário o hibernate já provê as mesmas funcionalidades.

Por outro lado o JPA não faz parte do JEE, logo, vc é tão livre de o escolher como escolher o hibernate ou outro qq ORM.

[/quote]
então se o jpa não fosse jpa vc usaria ele? hahhhahahaha[/quote]

Eu não usaria ele a menos que servisse para mais coisas que banco de dados. sim.
É impossível testar um sistema usando JPA sem usar um banco de dados. A Testabilidade do JPA é inexistente. Ao menos com o hibernate dá para encapsular e abstrair a maior parte das coisas.

Se o JPA fosse realmente o Java Persistance API e não o Java ORM API , o mundo seria diferente.

[quote=sergiotaborda][quote=bobmoe][quote=sergiotaborda]
A JPA é tecnicamente mais limitada que o Hibernate. Ambos têm o mesmo alvo: banco de dados.
Então a unica coisa que faria usar o JPA seria uma independencia maior (que ele não tem) tanto em termos de modelagem, como em termos de execução. Por exemplo, se o JPA não fosse apenas para banco de dados, valeria a pena. Ou se ele fosse realmente agnóstico. Caso contrário o hibernate já provê as mesmas funcionalidades.

Por outro lado o JPA não faz parte do JEE, logo, vc é tão livre de o escolher como escolher o hibernate ou outro qq ORM.

[/quote]
então se o jpa não fosse jpa vc usaria ele? hahhhahahaha[/quote]

Eu não usaria ele a menos que servisse para mais coisas que banco de dados. sim.
É impossível testar um sistema usando JPA sem usar um banco de dados. A Testabilidade do JPA é inexistente. Ao menos com o hibernate dá para encapsular e abstrair a maior parte das coisas.

Se o JPA fosse realmente o Java Persistance API e não o Java ORM API , o mundo seria diferente.[/quote]

O JCP já tentou, Sérgio, criar uma abstração maior do que banco de dados relacionais através do JDO, mas não funcionou. Justamente pq o mundo corporativo persiste em “banco de dados relacionais”, qualquer abstração maior do que ORM seria uma limitação muito grande. O Hibernate brilhou justamente por causa disso… percebendo que não adianta querer abraçar o mundo em todas as formas de persistencia, Gavin focou seu framework na resolução do problema Objeto para Relacional, e foi feliz. O mesmo ocorreu com a especificação. Não acho isso errado, muito pelo contrário, acho prático …

[quote=Alessandro Lazarotti][quote=sergiotaborda][quote=bobmoe][quote=sergiotaborda]
A JPA é tecnicamente mais limitada que o Hibernate. Ambos têm o mesmo alvo: banco de dados.
Então a unica coisa que faria usar o JPA seria uma independencia maior (que ele não tem) tanto em termos de modelagem, como em termos de execução. Por exemplo, se o JPA não fosse apenas para banco de dados, valeria a pena. Ou se ele fosse realmente agnóstico. Caso contrário o hibernate já provê as mesmas funcionalidades.

Por outro lado o JPA não faz parte do JEE, logo, vc é tão livre de o escolher como escolher o hibernate ou outro qq ORM.

[/quote]
então se o jpa não fosse jpa vc usaria ele? hahhhahahaha[/quote]

Eu não usaria ele a menos que servisse para mais coisas que banco de dados. sim.
É impossível testar um sistema usando JPA sem usar um banco de dados. A Testabilidade do JPA é inexistente. Ao menos com o hibernate dá para encapsular e abstrair a maior parte das coisas.

Se o JPA fosse realmente o Java Persistance API e não o Java ORM API , o mundo seria diferente.[/quote]

O JCP já tentou, Sérgio, criar uma abstração maior do que banco de dados relacionais através do JDO, mas não funcionou.
[/quote]

Isso não totalmente verdade. O problema do JDO é a falta das pessoas o conhecerem. Veja que o Google App Engine usa JDO.
E tem uma implementação JPA em cima de JDO. E isso porque, lá no GAE não ha banco de dados, ha bigtable.
Mas isso tem um preço. Join não funciona. E não funciona porque é um conceito inerente, ou seja, o JPA não faz join, ele delega o join ao banco de dados. A capacidade de abstrair isso é nula.

Cuidado. Esse conceito persiste nas empresas médias e pequenas, não no mundo corporativo como um todo.
Veja que coisas como o bigTable , o movimento NoSQL e os bancos OO estão ganhando terreno.

Não vejo porque seria uma limitação se fosse bem feito. Repare, eu não estou dizendo que vc deveria ter implementações para todos os tipos de coisa
eu estou dizendo que o framework não deveria limitar isso ha partida. Quer fazer join, blz. Se o implementador suportar isso nativamente otimo, senão a implementação do framework deve simular isso. A principal questão é a falta de capacidade de teste, de fazer mocks, etc… É o mesmo problema da EJB 2.x que ainda persiste.

Vou-lhe dar um exemplo real. Eu implemento um sistema usando postgress. Ai eu quero colocar a funcionar no GAE. Não posso fazer isso com simples deploy. Não posso fazer isso sequer apenas substituindo o meu DomainStore, porque ele está vinculado ao conceito de banco relacional. Mas eu quero ter esse trabalho de adaptar a aplicação ao GAE? Não. O que que quero é ter componentes intercambiáveis.

E veja, ele até aceita JPA mas não aceita todo o JPA. Ou seja, duh! obriga vc a fazer um monte de coisas na mão.
Isso já para não falar em testabilidade.

O que JPA lhe dá? Aderência à JEE. Apenas e só. Mas ha muito tempo esta adrencia deixou de ser importante para 90% das aplicações.
Para ser importante vc precisa estar correndo aplicações que só podem funcionar em ambiente JEE.

Aderencia à JEE não significa universalidade, como todos sabemos.
Então, amarrado por amarrado é melhor amarrar-se com quem lhe dá mais capacidade e poderes , no caso o hibernate. e não me entenda mal, eu odeio o hibernate e acho que falta concurrencia, contudo dos dois males ele é o menor.

@sergiotarborda

Sergio, mais uma coisa, o meu padrao pode realmente nao ser o padrao repositorio (afinal sua literatura e bem pequena na internete) …

Pode ser o padrao DomainStore…

Mas uma coisa vc nao tem como negar, o nome esta correto, Repository, o padrao pode ate ser outro, mas chamar o lugar onde se guarda as entidades de Repositorio e’ nada alem do obveio, afinal e’ isso que e’ pra mim.

Pode ser que o padrao nao seja este, mas a nomeclatura esta coerente com o que o objeto tem como responsabilidade, que e’ guardar minhas entidades.

Cuidado. Esse conceito persiste nas empresas médias e pequenas, não no mundo corporativo como um todo.
Veja que coisas como o bigTable , o movimento NoSQL e os bancos OO estão ganhando terreno.

[/quote]

Médias e pequenas? Você esta dizendo que empresas grandes não utilizam banco relacionais? Sergio, isso não é verdade e esta longe de ser. Não acho interessante expor na internet o nome das empresas que ja participei / participo de projetos que utilizam banco de dados relacionais como seu maior repositório de dados. Contudo posso assegurar que as maiores indústrias do ramo automotivo, telecom, petroquímico e químico utilizam banco de dados relacionais… e não são de fato empresas de pequena e médio porte.

[quote=sergiotaborda]Vou-lhe dar um exemplo real. Eu implemento um sistema usando postgress. Ai eu quero colocar a funcionar no GAE. Não posso fazer isso com simples deploy. Não posso fazer isso sequer apenas substituindo o meu DomainStore, porque ele está vinculado ao conceito de banco relacional. Mas eu quero ter esse trabalho de adaptar a aplicação ao GAE? Não. O que que quero é ter componentes intercambiáveis.

E veja, ele até aceita JPA mas não aceita todo o JPA. Ou seja, duh! obriga vc a fazer um monte de coisas na mão.
Isso já para não falar em testabilidade.
[/quote]

JPA é O"R"M, ponto final. Se o seu sistema é um dos raros que querem persistir em outro meio que não relacional, não é a tecnologia correta a ser utiliza, não vejo onde esta o pecado nisso. Se você tem uma camada de persistência bem definida, melhor ainda, vc pode optar pela implementação ORM ou qualquer outra coisa, inclusive JDO.

Bom mas como já disse, se vc tem uma idéia de arquitetura diferente da minha, discutiriamos até amanhã sem chegar em um consenso. Simplesmente o que é aceitavel pra mim pode não ser pra vc, e vice-versa.

[]s