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

Com a nova (nem tão nova assim) onda de se utilizar JPA ao invés de Hibernate, surgem as questões…

Quase todo mundo que hoje utiliza JPA, tem como implementação o Hibernate que já utilizavam anteriormente…

O JPA introduziu novas interfaces e classes além do que já tinhamos que saber com o Hibernate. Mas o JPA não é uma especificação completa porque ainda é necessário em alguns momentos utilizar coisas especificas do Hibernate.

O JPA acabou introduzindo uma nova camada de persistencia e nós sabemos que camadas em cima de camadas trazem problemas.

Se a implementação de JPA que todo mundo utiliza é o Hibernate, qual é a utilidade de se ter JPA?

Seguinte…

Hiberante padrão não implementa JPA

vc pode usar ele direto, mas não vai conseguir usar tudo que o JPA oferece

o JPA oferece menos coisa que o Hibernate… mais oferece algumas coisas de forma diferente do hiberante com interface mais faceis…

o hiberante pra atender ao JPA criou um adaptador, o pactoe EntityManager, que implementa o JPA ou seja, ele nada mais faz que delegar pra interface do JPA os comandos corretos em uma Session…

Se vc usa Hiberante não pode usar @EntityListeners() por exemplo, para callbacks, vai ter que usar intereptors do hibernate…

Se vc usar JPA Puro, não vai ter várias coisas que só tem no Hiberante…

Solução ? cria o JPA usando o Hiberante… passa a poder usar tudo do HIBERNATE e tudo do JPA… cria os entitymanager normalmente… e pra pegar a session basta fazer

Session session = (Session)EntityManger.getDelegate();

A vantagem é que vc consegue usar os 2…

E fora isso quase todo mundo cria uma camada do seu projeto (ou com DAO, que eu desaprovo, ou com Repository, que é o que uso) …

No caso seu projeto conversa como Repository ou DAO que é um adpatador para o JPA (ou diretamenteo hibernate) que é um adaptador para a Session (no caso de usar jpa) …

Assim seu projeto passa a depender de uma estrutura propria, o Repository ou o DAO … e se omundo cair, explodir, houver uma guerra, e vc resolver mudar no proximo projeto a implementação de persistencia, vai continuar utiliando sua estrutura de DAO ou Repository, e assim sua Lógica, fica protegida dessa sua escolha de persistencia

Entendi…

Mas o que eu questiono é o seguinte… se na verdade você mesmo usando JPA, vai estar utilizando é o Hibernate…

Pra que JPA?? Porque nao usar o Hibernate direto como sempre foi feito?

Que vantagem tem no JPA??

(Entende o que eu quero dizer?)

[quote=rogelgarcia]Entendi…

Mas o que eu questiono é o seguinte… se na verdade você mesmo usando JPA, vai estar utilizando é o Hibernate…

Pra que JPA?? Porque nao usar o Hibernate direto como sempre foi feito?

Que vantagem tem no JPA??

(Entende o que eu quero dizer?)[/quote]

não é exatamente igual… JPA é uma interface… é uma especificação, ele não é uma implementação, ele vem pra dizer…

quer criar um pacote de persistence ? use a interface JPA, usando esssa interface vc poderá ser escolhido por quem utiliza JPA

Hiberante é uma implementação real, e nã nasceu pra implementar o JPA, por isso ele tem suas proprias interfaces, e tem mais recurso que a implementação do JPA poderia pedir…

Para solucionar o Hierante criou um Adaptador… que simplismente atende a tudo do JPA, a 100% da especificação JPA, e continua funcionando como antes, com a espcificiação do Hiberante…

Usar hiberante sozinho, não vai ter as funcionalidades do JPA…

por exemplo

[code]@Entity
@EntityListners(Auditor.class)
public class Entidade {

}

publci class Auditor {
@PrePersist
void antesDePersistir(Entidade entidade) {
entidade.setDataCriacao(new Date());
}
}[/code]

por exemplo, se vc criar uma SessionFactory, e tentar persistir uma Entidade, ela não vai chamar o Auditor, e assim setar a data correta de criação.

Porem criando uma EntityManagerFactory, ele vai fucionar, mesmo que a implementação seja o Hiberante…

a maioria das anotações são do JPA e não do Hiberante, e anotação é melhor q xml, mais um motivo pra pelomenos instnaciar pelo JPA

Sim… eu sei que JPA é só uma especificação e Hibernate é uma implementação… isso é claro pra mim…

A minha questão é… pra que JPA? Qual a vantagem eu tenho em relação a usar só o hibernate?


Sobre a questão do Listener, isso é só uma forma diferente de fazer a mesma coisa que é possível fazer com hibernate…

E o hibernate tem o hibernate annotations… então trabalhar com annotations no hibernate nao é problema… mesmo sem usar JPA


O que eu quero dizer é… o Hibernate atende, inclusive melhor que se usar só a interface JPA… entao pra que eu vou querer JPA?

O que eu to querendo chamar a atençao… é que parece invenção de moda… entende?

[quote=rogelgarcia]Sim… eu sei que JPA é só uma especificação e Hibernate é uma implementação… isso é claro pra mim…

A minha questão é… pra que JPA? Qual a vantagem eu tenho em relação a usar só o hibernate?


Sobre a questão do Listener, isso é só uma forma diferente de fazer a mesma coisa que é possível fazer com hibernate…

E o hibernate tem o hibernate annotations… então trabalhar com annotations no hibernate nao é problema… mesmo sem usar JPA


O que eu quero dizer é… o Hibernate atende, inclusive melhor que se usar só a interface JPA… entao pra que eu vou querer JPA?[/quote]

A pergunta na verdade é ao contrario …

Pra que se amarrar única e exclusivamente ao Hiberante ? se eu consigo mapear todas as minhas entidades com JPA ? e assim posso usar outra Unidade de persistencia como Link por exemplo, no caso de um dia precisar ?

vc não conhece o amanha, e em java uma das boas praticas dizem… não programe para implementação, programe para a interface… e é isso que é programar para o JPA

por exemplo vc já deve ter cançado de ver isso escrito por ai

e vc já se perguntou ? pq não fazer

já que uma arraylist é mais poderosa que apenas a interface ? afinal a arraylista tem implementações, e pode ter propriedades únicas…

o problema de fazer isso é que vc amarra a droga da ArrayList, e existem outros tipos de lista por ai!

e se vc fizer um método

[code]
public void queroUmaLista(ArrayList<?> meDaAlista) {

}[/code]

vai acabar se ferrando, pq por exemplo, a lista do Hiberante é uma PersistenceBag, e não uma ArrayList, e não vai conseguir usar…

subindo o nivel, para a interface mais abrangende, vc abre o leque de opções…

[code]
public void queroUmaLista(List<?> meDaAlista) {

}[/code]

tem um nivel de acoplamento muito mais baixo… pois aceita muito mais gente

e digo mais! se dentro dessa lógica, vc tiver apenas um FOR, mesmo que em seu projeto vc saiba que só tem list, vc deve escrever Collection<?> e não List<?>

por isso

public void queroUmaLista(Collection&lt;?&gt; meDaAlista) { for(Object item : meDaAlista) { //tem muito mais reusabilidade que os códigos acimas } }

Acho que é muito improvavel alguém trocar de implementacao de JPA, isso é trocar seis por meia dúzia…
E aposto o que for… que nessa troca vão haver bugs… pois não teria vantagem trocar de implementacao a nao ser pra usar as coisas especificas…

Pelo que eu já vi na minha vida isso nao funciona… é bonito na teoria mas na pratica é diferente…

E pra voce chegar a trocar isso o sistema tem que ser tão antigo… e vai ter tantas coisas novas… e incompatíveis com o que já foi feito…

Valeria a questão das várias implementações de JPA… se a especificação fosse boa…

JPA na verdade foi criado baseando-se no hibernate… Fizeram ao contrário da sua lógica… primeiro fizeram a implementacao… depois a interface… ou seja… a interface ficou atrelada a implementacao do mesmo jeito…

Mas valeu seus comentários… vamos ver como esse negócio de JPA caminha…
Na minha humilde opinião… só tá servindo pra complicar :smiley:

O exemplo da lista eu considero mais pertinente que o JPA… pois a interface é bem definida… e tem várias implementacoes… uma para cada situacao…

Acho que o povo gasta fosfato demais pensando coisas cabulosas… em vez de pensar no simples…

quer ver um exemplo

A anotação @ManyToOne… já é fetch EAGER por default…

se vc quiser LAZY tem que colocar em todas as annotacoes…

olha que saco… ao invés de vc configurar isso uma vez só na sua aplicacao…

Ao invés de o povo preocupar com coisa útil… fica viajando… em super arquiteturas…

Por isso os Rails tao aí dominando tudo… é facil e tem um jeito de fazer e bem feito…

nop, JPA foi criada para o Link, que era da oracle, e foi passada a eclipse fundation, e a implementação do JPA2 que tem muita base no hiberante, principalmente em criteria…

O reuso não é exatamente do seu projeto, vc não vai pegar seu projeto, e apagar o Hiberante e enfiar um TopLink um EclipseLink ou coisas do tipo…

Mas vc pode se ver na situação de pegar um projeto usando EclipseLink, e simplismente não conhecer nada de JPA e nada de EclipseLink, e acabar não conseguindo reutilizar nada que ja usou na vida, apesar de ter anos de experiencia com ORM não vai conseguir se dar bem nesse novo projeto…

o que vc reusa são os componentes, por exemplo… eu tenho várias entidadees, que dou CTRL+C e CTRL+V em novos projetos… e não tenho que alterar 1 virgula…

se pegar um projeto diferente do meu mundo, pelomenos eu escrevi elas para algo de aceitação geral…

por exemplo,

se vc escrever

session.save(entity); … só vai reusuar em ambiente com hibernate

se usar entityManger.persist(entity); … já vai poder reusuar em qualquer ambiente com JPA, e isso inclui o proprio hiberante

se usar repository.add(entity) … vai poder escrever seu repositorio, e poder reusar a lógica criada em qualquer lugar

e se seu novo projeto não for com hiberante, vc precisará reescreverapenas o repositorio, mas nunca reescrever todo chamada a um .persist, ou .save

e não to falando isso pq é bonito, ou é lindo na teoria, isso é pratica, e enclusive se chama boas praticas ^^

Tópico legal…

A Sun sempre faz isso… pega as boas idéias do mercado e documenta… específica, padroniza, acho muito legal isso…
Ao meu ver a única vantagem mesmo de utilizar em uma implementação JTA, apenas o que está especificado pela Sun, é a possibilidade de troca da implementação…
Mas, convenhamos, ninguém faz isso, como já foi dito anteriormente…

abss

Entendi… a proposta… é um ambito maaaiorrr do que eu estava pensando…

Pro projeto que eu faço aqui … nao tem validade mesmo nao…

Tem caso eu for passar esse projeto pra alguém… ele vai estar mais padronizado…

(eu to ligado nas boas praticas… eu concordo também… mas o que fico indignado é que ao invés de resolver o problema mesmo… o povo fica querendo crescer e crescer e inventando coisas… se o que já existe nem tá tao bom assim…
já fuçei muito o código do hibernate… que tragédia… de boas práticas aquilo passou longe… hahhah)

Eu uso o hibernate… mas acho ele muito limitado… mas num tem outro né?!

[quote=rogelgarcia]Entendi… a proposta… é um ambito maaaiorrr do que eu estava pensando…

Pro projeto que eu faço aqui … nao tem validade mesmo nao…

Tem caso eu for passar esse projeto pra alguém… ele vai estar mais padronizado…

(eu to ligado nas boas praticas… eu concordo também… mas o que fico indignado é que ao invés de resolver o problema mesmo… o povo fica querendo crescer e crescer e inventando coisas… se o que já existe nem tá tao bom assim…
já fuçei muito o código do hibernate… que tragédia… de boas práticas aquilo passou longe… hahhah)

Eu uso o hibernate… mas acho ele muito limitado… mas num tem outro né?![/quote]

esse é o fato… tem outro sim… e épra isso que o JPA esta ai… pra ter muitooosssss outros…

antes só existia as coleções do Java Collections Framework… hoje quase todo mundo usa as do google pq são melhores (sem falar que a um tempinho atras tinhas ainda as da apache)… imagina se vc programasse pra implmentação ? apenas por saber que… implentação X é a melhor ?

Exite TopLink, EclipseLink, que seriam como versão 1 e 2, de uma mesma base… existem mais, acredito, mas pelomenos tem essas

o EclipseLInk vem como padrão no Eclipse, e tem muita gente que usa… claro que nem se compara a quantidade que usa hiberante…

pensar só no seu projeto, vc não vai longe… com certeza um dia, vc vai mudar de projeto, e abranger a quantidade de código que vc possa reusar é bom, na hora de mudar de abordagem

Eu falei que nao tinha outro… nao tinha outro bom… ou que fizesse a mesma coisa… que o hibernate

Já tentei trabalhar com esses outros…mas eles pecam mais do que o hibernate ainda… nao gostei…

Acho que entao a filosofia de se construir o JPA teria que ser diferente… partindo de uma interface bem pensada… e nao de implementacoes…

Voce tem que programar para interfaces… concordo plenamente… mas e se a interface é ruim?!

O JPA em si é valido… como tá sendo feito é que eu acho que nao é…

Eu mesmo já pensei numa especificacao de um framework de persistencia… muito mais flexivel que o hibernate por exemplo…

Se o JPA se limitar ao que o Hibernate faz… nao vai adiantar nada…

já leu sobre o JPA 2 ?

a especificação na verdade é um ponto de convergencia…

dificlmente uma especificação vai correr a frente da implementação… afinal novas ideias aparecem o tempo todo… e a especificação é um conjunto das melhores… e tenta reunir tudo em um sento comum e ponto comum…

realmente tem loucuras de bancos legados que é foda de fazer com JPA e da dor de cabeça… e vc acaba usando anotações do Hiberante… mas no geral, pra anotaçõeso JPA cobre tudo… desde que não seja um banco maluco legado…

Para buscas, eu não troco os Criterias pelas HQLs do JPA, mas também não exponho elas para meu projeto, e uso objetos Queries, para meu projeto não tercontato com o Hiberante, e sim com uma interface de mais alto nivel…

assim posso continuar reusando… por exemplo, trocar do Hiberante 3 para a proxima versão que vai implementar o JPA 2, vai ser relativamente fácil para meus projetos, pois só vou reescrever a camada de persistencia, um conjunto de 8 classes no máximo.

Lógico que não vou pegar meu projeto que ta escrito com criterias 3.x, e com hiberante e etc, e enfiar o Hibernate novo para JPA 2, pq isso seria sem sentido… porem vou conseguir reusuar a mesma lógica em novos projetos, sem ser afetado pela camada de persistencia…

Obs.: eu entendo sua revolta… já pensei igual, mas me ajudar muito, conseguir não programar diretamente com o hiberante…

aqui vai um exemplo de código em meus projetos…

[code]repository.addAll(carros);
repoistory.removeAll(telefones);

List<PessoaFisica> pessoasAtivas = queries.forPessoa().listPessoasAtivas().queryOn(repository);
[/code]

todas são de facil leitura, Repository éuma INterface… e a implementação normal que uso é pra Hiberante… mas já precisei usar pra SQL puro entre outras firulas, por questões diversas

em momento algum em meu projeto há um new HibernateRepository … quando não uso algo como spring, o HiberanteRepository vem sempre de algo como

Repository repository = minhaFabrica.createRepository();

no caso é só trocar o que vem do CreateRepository e voala! … mudo a implementação facilmente…

Muito legal cara… to vendo que voce é um cara conhecedor do assunto…

Fiquei curioso sobre o Repository… tem algum artigo interessante sobre isso?

Procurei na internet mas só vi gente perguntando sobre a diferença entre repository e dao e poucas explicacoes…

eu iniciei lendo no blog do sergio taborda http://sergiotaborda.wordpress.com/desenvolvimento-de-software/java/patterns/repository/

depois fui fazendo a minha maneira…

A entender, a diferenca basica do DAO pro RESPOSITORIO, e’ que o DAO acumla as queries dentro dele, e por isso vc sai criando 1 DAO por Entidade… isso traz dificuldade, pois uma Session funciona com um repositorio, ela funciona igual seja a entidade qual for…

Entao o repositorio tem aceita objetos em seus metodos, e asism repository.add(Object o); e assim para cada operacao,

Tudo que for generico vc deixa no repositorio, ou seja

<T> List<T> repo.list(Class<T> target);
<T> T repo.get(Class<T> target, Object id);
repo.refresh(Object object);

etc etc etc

e as queries as consultas, vc separa coloca em outro objeto, eu crirei uma interface pra fazer isso…

e no fim, eu executo uma Query em um Repository,

que para o hiberante eu so faco pegar um DatechedCriteria que esta dentro do queries, e unir a session dentro do repository, e assim a magica da consulta acontece…