Iniciando com JPA

JPA, acrônimo de Java Persistence API, que veio junto com o Java EE 5, trouxe diversas funcionalidades que ajudam e muito a vida dos desenvolvedores. A JPA faz parte da especificação EJB 3.0, porém à rumores de que na versão 6 do Java EE ela seja retirada dessa especificação.

A JPA é caracterizada em três áreas:

  • Java Persistence API
  • Query Language
  • Mapeamento Objeto/Relacional

Logo abaixo irei dar exemplos de como inserir uma entidade no banco de dados, utilizando as annotations do EJB 3.0, os objetos do JPA , o banco de dados MySQL 5.0 e o Oracle TopLink como provider.

Iremos precisar de algumas libs para este exemplo, no final do post tem um link para você baixar o exemplo completo, com as classes e as libs necessárias.

- Criando a entidade
Iremos criar a nossa classe de entidade chamada Usuario, que irá possuir os seguintes atributos: id, login, password e nome.
Ela nada mais é do que um simples POJO (Plain Old Java Ob
ject) com alguns atributos, métodos acessores e não herda de nenhuma classe. Em aplicações coorporativas que utilizam toda a especificação EJB é necessário que essas classes possuam mais características, como serialização por exemplo.

Vamos aos códigos:

Figura 1


Na linha 10 eu informo que esse objeto será uma entidade, marcando com a annotation @Entity.
Na linha 11 informo o nome da tabela, atráves da annotation @Table, usando o atributo name da mesma.

Já na linhas 14 e 15, indico que este atributo será um id (marcado com a annotation @Id) e que a sua estratégia de geração de valores no banco será IDENTITY (para o Oracle usa-se SEQUENCE).
Os demais atributos são marcados com @Column, porém não é necessário fazê-lo, a menos que você quizesse utilizar alguns dos atributos dessa annotation, como name, que indica qual vai ser o nome da coluna no banco.

- Criando a classe UsuarioDAO para persistência

Como este post é apenas um exemplo simples de persistência utilizando JPA, criei apenas uma classe DAO (padrão de projeto Data Access Object) que contém o código principal para a persistência.

Figura 2

Na linha 18 eu crio meu objeto factory, recebendo a instância do provider, que irá encontrar o nome do persistence-unit no arquivo persistence.xml.

Em seguinda, na linha 19 eu crio o objeto EntityManager, que é o principal objeto para a persistência na JPA.

O método inserirUsuario utiliza o objeto EntityTransaction, para transações.

Na linha 35 o objeto eu chamo o método persist do objeto EntityManager, passando a entidade para ser gravada no banco.

Existem vários outros métodos relacionados a persistência, como o find, delete, merge e outros. Aconselho dar uma lida na especificação para conhecer estes métodos, quais seus propósitos e suas funcionalidades.

- Arquivo de configuração (persistence.xml)

Esse é o arquivo de configuração, que configura o nome da unidade de persistência, o tipo de transação, as configurações de banco, o provider, as classes de entidades e etc.

Figura 3

Atenção para a linha 15, essa propriedade informa o tipo de geração das tabelas do banco. Na primeira vez que você rodar o exemplo, o provider irá criar as tabelas no schema exemplojpa.

Se você tentar rodar novamente o exemplo sem comentar ou tirar essa linha, irá gerar um erro informando que já existe uma tabela criada no banco, mas os dados irão ser persistidos. Então ao rodar a primeira vez, comente essa linha ou troque o tipo de geração.

Abaixo você poderá fazer o download do exemplo, com as classes, as libs e o persistence.xml (arquivo de configuração).

Este exemplo foi bastante simples e a JPA é bastante vasta, portanto baixe as especificações e estude mais afundo sobre esse excelente meio de persistência!

Download do exemplo
Screencast excelente sobre JPA

Tags: , ,

22 comments

  1. Rafael Tabosa

    E ai Rafa, muito legal o artigo, bastante prático para quem quer dar o ponta pé. Estou pensando seriamente de utilizar JPA nos próximos projetos , queria saber se a tecnologia já esta madura, existe algum bug ou impossibilidade no jpa quando os relacionamentos entre as classes são mais complexos ? O pessoal já esta utilizando JPA em larga escala nos projetos ?
    Abraços

  2. Rafael Carneiro

    Oi Tabosa, obrigado pelo elogio, o seu blog também está excelente, espero que o conteúdo do meu chegue próximo do seu. Sobre o uso da JPA, atualmente estou num projeto de grande porte que a utiliza, sem problemas. No blog do Urubatan ele postou recentemente as novidades sobre a JPA anunciadas no Java One.

  3. ta virando moda é fazer blog?!

    vou fazer o meu, mas para contar as minhas putarias, pq java no máximo 12 horas por dia :P

    P.S.: Num sei quem é o mais bajulador dos dois aí em cima :P

  4. Que explicaçao como instalar jdk

  5. Oi Washington,

    não entendi a sua afirmação. Para fazer esse artigo eu parti da premissa que os leitores já tivessem pelo menos a JDK instalada na máquina.

    Poderia ser um pouco mais claro?

    Abraços.

  6. O link para download do exemplo está quebrado, por favor seria possível disponibilizar outro link para download do material?

  7. @Dirceu

    o arquivo estava no servidor antigo do PortalJava. Agora o PortalJava está no ar rodando em Java e o arquivo foi modificado.

    Até amanhã estarei consertando esse problema.

  8. Olá Rafael, tudo bem?? será que você pode me ajudar a esclarecer uma dúvida….
    se eu fosse inserir diversos metodos de negocios, deveria inserir na classe de entidade?? ou criar uma outra classe, uma classe de negocio??
    ou da minha tela qdo for instanciar algum objeto, instancio direto a classe de entidade???
    abrigado Rafael
    at
    Jonathan Martinez

  9. @Jonathan,

    isso vai depender da arquitetura e definição do seu modelo. Estão falando muito de DDD, acrônimo de Domain Driven Design, e uma das abordagens dele é que o objeto deve ter estado e comportamento, deixando assim de ser um objeto burro. Então muita gente em muitos fóruns tem falado que é importante que as regras de negócio fiquem no próprio objeto. Também há pessoas que preferem deixar as entidades “burras” e colocar as regras de negócio em classes de negócio, em classes diferente.

    Minha opinião: eu acho que devemos programar orientação a objetos de uma forma correta, e como o DDD prega eu acho que seria a melhor escolha.

  10. Eu tb acredito que é melhor não deixar a entidade burra, pelo fato de que teriamos, duas classes com os mesmos atributos… parece redundancia….
    bom, vlw Rafael
    até mais
    Jonathan

  11. Muito bom.fiquei sem entender pq além de biliotecas toplink há libs “hibernate”.Vc não usou TopLink como provider?
    valeu!!!

  12. Oi Ricardo,

    na verdade a lib hibernate3.jar pode ser removida do projeto.

  13. Oi Rafael,
    Eu tive alguns problemas porque não tinha configurado o MySQL direito. Na verdade, eu não “cadastro” o usuário admin (ou root), então o password devia ficar “”.
    Gostei bastante do artigo.
    Abraço!

  14. Rafael, encontrei por acaso seu blog e era justamente isto que eu precisava, incrível como economizei horas de trabalho ao invés de implementar os massantes DAOs.
    Valeu mesmo, até mais e já favoritei seu blog aqui.

  15. @Douglas
    Obrigado! Espero escrever mais posts sobre JPA e afins.

  16. Rafael,
    Fiz uma busca rápida, e tvz seu post seja o único em português que trate do uso de JPA sem um conteiner JEE. Realmente merece os parabéns por isso.
    Seu post está me ajudando muito. Porém tenho um problema. Estou fazendo uma aplicação semelhante a do seu exemplo, com mais de uma centena de classes POJO. E as bibliotecas de persistência (tanto TopLink quanto Hibernate) apresentam erros semelhantes ao seguinte nos relacionamentos @ManyToOne:
    [class entidades.CargoNivel] uses a non-entity [class entidades.Cargo] as target entity in the relationship attribute [private entidades.Cargo entidades.CargoNivel.cargo]
    Já verifiquei e as mesmas estão corretamente nomeadas no persistence.xml.
    Já até pesquisei no esquema XML http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd mas não achei nenhuma informação referente.
    Será que eu tenho que declarar os atributos do persistence na ordem de acessibilidade das mesmas (de acordo com os relacionamentos)?
    Se sim, acredito que este ordenamento seria inviável de forma manual em projetos maiores.

    Grato desde já por qualquer ajuda sua ou dos leitores de seu post.

  17. @Lazarus
    Consegui resolver. Não era nada do que pensei.
    Alterei o value da property name=”toplink.logging.level” para “FINE” e pude ver claramente os vários erros de modelagem que deixei passar…
    Agora está tudo funcionando direito. E posso dar continuidade ao projeto.
    Muito obrigado pelo artigo!

  18. @Lazarus
    Que bom que você conseguiu solucionar o problema! Obrigado pelos comentários!

  19. Rafael, meus parabéns pelo artigo. trabalho com jpa faz algum tempo mas queria achar uma aplicação que mostrasse o jpa independente de EJB, o que acabei encontrando no seu blog… baixei o exemplo e fiz as devidas alteracoes pra ficar de acordo com a minha base de dados tudo deu certo. Agora tenho uma idéia mais completa de como integrar jpa com outros frameworks, vlw!

  20. Prezado Rafael,
    Encontrei seu artigo hoje e achei uma boa fonte de pesquisa para iniciantes (claro e sucinto)! Estou treinando uma equipe em JPA e vou recomendar que leiam o mesmo!
    Meus sinceros parabéns pelo seu bom trabalho claramente inpirado na documentação da Sun, mas elegantemente simplificado!
    MaLSan

Leave a comment