Olá, tudo bom? Como vão vocês?
Este artigo é o segundo de uma série ao qual vou ensiná-los a trabalhar com a Java Persistence API 2.0 (JPA 2.0). Dúvidas e críticas são bem vindas.
Os primeiros passos na JPA
Com o ambiente configurado, agora podemos configurar a JPA e dar nossos primeiros passos em sua execução, entendendo como funciona e o que podemos fazer.
Esta parte do artigo está baseada na configuração, criação da entidade e manipulação básica do banco de dados.
Caso você tenha chegado agora, a Parte 1 do artigo ensina como configurar o seu ambiente de desenvolvimento e testes.
Configurando o arquivo persistence.xml
Ao criar o projeto, também foram criados um diretório e arquivo. Note o arquivo chamado persistence.xml, encontrado no diretório META-INF, dentro de src.
Abra o arquivo persistence.xml e verá que o Eclipse IDE possui um editor do arquivo.
Sua estrutura básica é como mostrada na Listagem 1 abaixo:
Listagem 1 – O arquivo persistence.xml
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit> </persistence-unit> </persistence>
Ela pode ser visualizada no Editor do Eclipse, em Source.
Configurando a conexão com o banco de dados
No editor do Eclipse, vá na aba Connection, em persistence.xml.
Comece alterando para Resource Local em Transaction type.
Esta pequena alteração adiciona o atributo transaction-type com o valor “RESOURCE_LOCAL” em <persistence-unit/> no arquivo persistence.xml. O atributo transaction-type está definindo que a unidade de persistência terá sua integridade gerida através da API local (RESOURCE_LOCAL), que é o nosso caso, onde não haverá um servidor de aplicativos Java EE por enquanto envolvido para transações JTA (Java Transaction API).
Mais abaixo, em EclipseLink Connection Pool, clique em Populate from Connection.
Ao abrir a caixa de diálogo Connection Selection, selecione a conexão do MySQL que fez na criação do projeto e confirme.
Ao retornar ao arquivo persistence.xml, os dados pertencentes ao banco de dados estarão preenchidos.
Esta mudança da conexão alterou o arquivo persistence.xml da seguinte forma:
<properties> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpapratica"/> <property name="javax.persistence.jdbc.user" value="edson"/> <property name="javax.persistence.jdbc.password" value="integrator"/> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> </properties>
Na JPA 2.0, algumas propriedades foram padronizadas. As propriedades que foram adicionadas ao arquivo persistence.xml são padrões para se conectar ao banco de dados. Veja o que significa cada uma delas:
- javax.persistence.jdbc.driver — o nome do driver da classe totalmente qualificado
- javax.persistence.jdbc.url — URL específico do driver
- javax.persistence.jdbc.user — usuário do banco de dados para a conexão
- javax.persistence.jdbc.password — senha do banco de dados para a conexão
Vá agora até a aba Logging e, em Logging level, altere para All. Isso tornará visível todas as operações que fizemos, utilizando a JPA, no Console do Eclipse.
Infelizmente, nem todas as propriedades de persistence.xml foram padronizadas. A seguinte propriedade foi adicionada ao arquivo:
<property name=“eclipselink.logging.level” value=“ALL”/>
Ainda em persistence.xml, vá até a aba Schema Generation. Nesta aba temos DDL generation type. Como não fizemos nenhuma tabela no banco de dados, teremos que criá-la ao executar nossa primeira entidade.
Temos três opções:
- None – não ocorre nada;
- Create Tables – cria as tabelas baseando-se nas informações contidas nas entidades;
- Drop and Create Tables – exclui e cria as tabelas através das informações contidas nas entidades;
Para o nosso trabalho inicial, vamos manter um ciclo de criação e exclusão, selecionando Drop and Create Tables.
As últimas alterações incluíram a seguinte propriedade:
<property name=“eclipselink.ddl-generation” value=“drop-and-create-tables”/>
Com estas mudanças, temos tudo pronto para trabalhar com a JPA.
Criando sua primeira entidade
Clique com o direito do mouse sobre src, do seu projeto JPA. Selecione no menu de contexto New>Entity.
Na caixa de diálogo New JPA Entity, preencha Java package e Class name, no caso: br.com.integrator e Categoria, respectivamente. Mantenha Entity em Inheritance e clique no botão Next.
Na segunda etapa, definimos o nome da tabela que será utilizada pela entidade Categoria e seus respectivos campos/colunas.
O Eclipse IDE, através do seu assistente, irá manter o nome da tabela como padrão existente ao nome da entidade. Desmarque Use default e altere para categorias em Table name.
Esta pequena alteração informa que a entidade Categoria está ligada a tabela categorias do banco de dados.
Abaixo você vai encontrar Entity fields. Clique em Add para adicionar as os atributos que existirão na entidade Categoria e seus respectivos tipos.
O diálogo Entity Fields possui Type para colocar o tipo ( que também é acessível com Ctrl+Space) e o nome.
Os atributos da entidade são mostrados na Figura abaixo:
Veja que foi marcado id como key. Isso fará com que este atributo/campo seja a chave primária.
Com tudo preenchido, clique no botão Finish para gerar a classe Categoria com as devidas anotações que a fará uma Entidade da JPA.
A classe/entidade Categoria possui a estrutura como mostrado na Listagem 2 após sua geração:
Listagem 2 – A entidade Categoria
package br.com.integrator; import java.io.Serializable; import java.lang.Long; import java.lang.String; import javax.persistence.*; @Entity @Table(name="categorias") public class Categoria implements Serializable { @Id private Long id; private String categoria; private String descricao; //getters e setters omitidos }
As entidades, na especificação da JPA, são POJOS (Plain Old Java Objects ), onde podemos alocar com o operador new, assim como faríamos com qualquer outro objeto Java simples. As instâncias de uma classe do tipo entidade não se tornam persistentes até estarem associadas a um EntityManager.
No arquivo persistence.xml, verá a classe adicionada em General>Managed Classes.
No XML de persistence.xml, haverá a seguinte linha adicionada:
<class>br.com.integrator.Categoria</class>
O elemento <class/> lista explicitamente as classes que são consideradas entidades no persistence.xml.
Para finalizar, vá até a classe Categoria. Na view JPA Structure, clique em id. Marque Primary key generation na view JPA Details e selecione Identity em Strategy. Isso informa a entidade que o campo da chave primária é auto-incrementado e, portanto, gerado pela tabela do banco de dados.
Na classe veremos a seguinte anotação: @GeneratedValue(strategy = IDENTITY), onde IDENTITY é de javax.persistence.GenerationType.
Testando a JPA
Antes de explicar qualquer coisa, vamos fazer um teste para saber se está tudo corretamente funcionando, simplesmente chamando a persistence-unit através de uma simples classe Java com um método main().
Crie uma classe no próprio projeto JPA , chamando-a de TesteDaJPA. Coloque em um pacote diferente do qual vem usando e marque public static void main(String[] args). Confirme a criação da classe no botão Finish.
Altere a classe TesteDaJPA conforme a Listagem 3:
Listagem 3 – A classe TesteDaJPA
package br.com.integrator.teste; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; public class TesteDaJPA { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("JpaNaPratica"); EntityManager em = emf.createEntityManager(); em.close(); emf.close(); } }
Execute a classe através do menu Run>Run As>Java Application.
Graças à configuração que fizemos de logging no arquivo persistence.xml (em <property name=“eclipselink.logging.level” value=“ALL”/>) , possuímos uma saída bem detalhada do que ocorreu ao gerar este simples teste.
Assim que iniciada a classe, veremos a saída contendo a conexão ao banco de dados:
[EL Finest]: 2010-02-03 04:33:36.007--Thread(Thread[main,5,main])--DBPlatform: org.eclipse.persistence.platform.database.MySQLPlatform, RegularExpression: (?i)mysql.*.
[EL Fine]: 2010-02-03 04:33:36.007--Thread(Thread[main,5,main])--Detected Vendor platform: org.eclipse.persistence.platform.database.MySQLPlatform
[EL Config]: 2010-02-03 04:33:36.022--ServerSession(11025290)--Connection(29232906)--Thread(Thread[main,5,main])--connecting(DatabaseLogin(
platform=>MySQLPlatform
user name=> "edson"
datasource URL=> "jdbc:mysql://localhost:3306/jpapratica"
))
[EL Config]: 2010-02-03 04:33:36.022--ServerSession(11025290)--Connection(9616314)--Thread(Thread[main,5,main])--Connected: jdbc:mysql://localhost:3306/jpapratica
User: edson@localhost
Database: MySQL Version: 5.1.43-community
Driver: MySQL-AB JDBC Driver Version: mysql-connector-java-5.1.10 ( Revision: ${svn.Revision} )
[EL Config]: 2010-02-03 04:33:36.022--ServerSession(11025290)--Connection(23255990)--Thread(Thread[main,5,main])--connecting(DatabaseLogin(
platform=>MySQLPlatform
user name=> "edson"
datasource URL=> "jdbc:mysql://localhost:3306/jpapratica"
))
[EL Config]: 2010-02-03 04:33:36.038--ServerSession(11025290)--Connection(16496587)--Thread(Thread[main,5,main])--Connected: jdbc:mysql://localhost:3306/jpapratica
User: edson@localhost
Database: MySQL Version: 5.1.43-community
Driver: MySQL-AB JDBC Driver Version: mysql-connector-java-5.1.10 ( Revision: ${svn.Revision} )
[EL Finest]: 2010-02-03 04:33:36.069--ServerSession(11025290)--Thread(Thread[main,5,main])--sequencing connected, state is NoPreallocation_State
Entre a saída, veremos que, devido a configuração no persistence.xml (em <property name=“eclipselink.ddl-generation” value=“drop-and-create-tables”/>) , primeiro houve uma tentativa de fazer um drop table na tabela categorias. Como não existia tal tabela, veremos este erro:
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown table 'categorias'
Error Code: 1051
Call: DROP TABLE categorias
Query: DataModifyQuery(sql="DROP TABLE categorias")
Em seguida veremos a criação da tabela na seguinte linha:
[EL Finest]: 2010-02-03 04:33:36.163--ServerSession(11025290)--Thread(Thread[main,5,main])--Execute query DataModifyQuery(sql="CREATE TABLE categorias (ID BIGINT AUTO_INCREMENT NOT NULL, CATEGORIA VARCHAR(255), DESCRICAO VARCHAR(255), PRIMARY KEY (ID))")
Por fim, será possível ver que ocorre a desconexão ao banco de dados.
A tabela gerada no banco de dados
Ao entrar no banco de dados, veremos que a simples classe anotada se transformou em uma tabela. Evidentemente que o POJO, sem a devida configuração no arquivo persistence.xml, antes da sua chamada pela classe executora que fizemos de teste, não teria esse poder.
Graças a anotação @Table, pudemos dar o nome da tabela que seria gerada, através do atributo name.
Observe que cada atributo da classe se transformou em uma coluna na tabela. A coluna chave, tida por ID, foi gerada graças à anotação @Id. Além disso, o MySQL considerou esta coluna como auto-incrementada, ou seja, ela possui um modificador que incrementa em um toda vez que uma informação é inserida na tabela. Isso é automático e gerenciado pelo banco de dados. A anotação @GeneratedValue foi a responsável pela geração do auto-increment do MySQL.
Os tipos de cada coluna são gerados pelo similar em Java. Logo, Long se transformou em bigint e String em varchar. Cada tipo de coluna, na tabela do banco de dados, possui também um tamanho definido na sua criação. Como não especificamos isso na classe Categoria, através de anotações, a tabela foi gerada utilizando o tamanho máximo obtido pelo tipo, isso no banco de dados em questão. Logo, Long se transformou em bigint(20) e String em varchar(255).
Na próxima parte
Na Parte 2 da série JPA 2.0 na Prática finalmente fizemos a configuração da JPA, possibilitando a conexão ao banco de dados. Também foi possível gerar uma tabela baseada em uma entidade da JPA através de um pequeno teste de utilização.
Em JPA 2.0 na Prática – Parte 3, começaremos a compreender a Entidade em questão, suas várias anotações e implicações no banco de dados.
As entidades, na especificação da JPA, são POJOS (Plain Old Java Objects ), onde podemos alocar com o operador new, assim como faríamos com qualquer outro objeto Java simples. As instâncias de uma classe do tipo entidade não se tornam persistentes até estarem associadas a um EntityManager.
No arquivo persistence.xml, verá a classe adicionada em General>Managed Classes.
fevereiro 5th, 2010 9:53
Muito bom este tutorial
Ficou muito mais claro apesar de eu já ter lido o seu livro de JSF com Spring.
Estou ancioso para a próxima parte
Abraço
fevereiro 7th, 2010 2:24
Edson no passo de configurar o arquivo persistence.xml o meu editor do eclipse não possui todas essas abas igual da figura eu baixei a versão 3.6 M5 32 bits.
fevereiro 7th, 2010 3:05
@Felipe,
O Eclipse pode estar abrindo o XML em outro editor. Clique com o direito do mouse sobre o arquivo persistence.xml, na view Project Explorer. Selecione o item Open With>Persistence XML Editor.
fevereiro 7th, 2010 16:03
@Edson,
O editor esta correto realmente não sei o que aconteceu, por exemplo falta a aba Logging
fevereiro 7th, 2010 16:56
@Felipe,
Então eu não sei o que pode estar acontecendo. Até instalei a versão M5 para verificar possíveis falhas, entretanto está igual ao editor do arquivo de persistência do M4.
fevereiro 7th, 2010 17:48
@Edson,
Cara eu baixei novamente o eclipse e deu certo deve ser que tava corrompido o arquivo por isso que não tava aparecendo.
fevereiro 11th, 2010 5:29
[…] JPA 2.0 na Prática – Parte 2, vocês verão como configurar, criar entidades e executar operações em JPA que serão refletidas […]
março 3rd, 2010 11:26
Olá,
Fiz os passos até aqui e funcionou, a tabela foi criada, o ínico problema no meu é que a Annotation @Table e a @Entity está dando um erro de que elas não pdoem ser resolvidas, porém nao sei o que pode ser.
março 3rd, 2010 13:28
@Crislaine, tudo bom!
É erro no Eclipse?
março 9th, 2010 14:39
Sim , o erro é no Eclipse, nas anotações do JPA:
@Entity
@Table(name=”categoria”)
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
fica sublinhado de vermelho como se a s bibliotecas nao estivessem ali, mas estão, e funcionou normalmente!
março 9th, 2010 15:13
@Crislaine, o Eclipse, que estou falando neste post, é ainda uma versão de desenvolvimento. Creio que esses bugs, que não aconteceram comigo, sejam resolvidos até a versão final.
março 16th, 2010 16:10
Olá Edson, estou com uma dúvida aqui:
O EclipseLink utilizaSQL nativo apenas ou ele tem algo parecido com Hibernate que tem o HQL?
Estou pesquisando porém não encontrei nada sobre.
março 16th, 2010 16:30
@Crislaine,
O EclipseLink utiliza a JPQL (chamado também de JP-QL/JPA-QL – Java Persistence Query Language). A JPQL é baseada na EJB-QL (Enterprise JavaBeans Query Language).
O Hibernate, quando utiliza a JPA, também trabalha com a JPQL.
Alguns links para visitar:
http://download.oracle.com/docs/cd/E11035_01/kodo41/full/html/ejb3_langref.html
http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/queryhql.html
http://en.wikipedia.org/wiki/EJB_QL
http://en.wikipedia.org/wiki/JPQL
Bons Estudos!
março 16th, 2010 16:40
ok! obrigada, vou dar uma estudada nisso!
abril 23rd, 2010 15:41
Ae cara muito obrigado parabens pela iniciativa.
Me ajudou muito.
Abraços!
setembro 14th, 2010 8:36
Muito bom mesmo suas postagens, parabéns Edson. Mais uma coisa, você teria alguma postagem sobre Web Service ? obrigado.
setembro 16th, 2010 0:21
@Carlos,
Sim, tenho um prontinho para submeter. Só está me faltando um tempo para transmitir para o meu blog.
outubro 27th, 2010 10:49
Eu também estou com o mesmo problema do Felipe Arimatéia. As únicas abas que aparecem são essas: General, Connection, Options, Properties e a Source. As outras não existem!
Já baixei novamente o Eclipse e nada. O arquivo não está corrompido, pois eu faço a verificação do checksum.
Não sei o que pode estar acontecendo. Acredito que seja alguma configuração na própria IDE que precise ser feita e que, por algum motivo, não foi necessária com você.
Caso alguém saiba de alguma solução, por favor, coloquem aqui!
De qualquer maneira, parabéns pelo artigo. Minha única crítica é com relação ao arquivo persistence.xml. Você poderia ter colocado ele na íntegra aqui. Assim ajudaria as pessoas que não conseguem fazer as abas que vc utiliza aparecerem.
março 16th, 2011 21:41
Também tive o mesmo problema de Felipe e Tiago: As únicas abas que aparecem são essas: General, Connection, Options, Properties e a Source.
Consultando a ajuda do Eclipse em:
Dali Java Persistence Tools User Guide > Reference > Property pages > persistence.xml Editor
E também em :
Dali Java Persistence Tools User Guide > Reference > Property pages
Diz que: essas abas aparecem em Generic platform, para ter todas as abas temos que usar a EclipseLink platform.
Para isso basta clicar com o botão direito no projeto e selecionar propriedades > java persistence > plataform e mudar para eclipselink.
Todas as abas aparecem no editor xml.
Parabéns, ótimos tutoriais.
abril 18th, 2011 22:41
Obrigado. Eu precisava deste pontapé inicial para continuar com o desenvolvimento de um sistema que utiliza o jpa.
setembro 18th, 2011 19:38
Edson mais um vez obrigado excelente tutorial, vou agora babando para a parte 3, muito obrigado! Fiquei apenas com uma dúvida, no caso sua classe main de teste vc utilizou um pacote (br.com.integrator.teste) que não criamos durante o tutorial, suponho que vc o tenha criado a parte do processo, se sim qual o motivo disso?? Fora isso tudo funcionou perfeitamente.(acabei por utilizar o br.com.integrator)
abs
setembro 23rd, 2011 1:11
@Heucles,
O tutorial foi feito de forma completa e depois fragmentado para ser explicado em detalhes. Por isso poderá ocorrer do leitor ver partes que não foram mostradas ou explicadas, não por erro do código, mas por falha minha na edição dos textos de remover aquela parte que não seria explicada neste ponto do tutorial.
julho 15th, 2012 19:28
Edson, mais uma vez obrigado pelos seus tutoriais. Já acompanhei outros, em outros tempos. O nivel de detalhamento e a didática que voce emprega nos tutoriais é de uma ajuda fantástica.
‘Thanks a lot’.
julho 23rd, 2012 23:17
Consegui resolver, era a versão do meu jar do eclipselinq que estava errado. Obrigado excelente tutorial. Muito Obrigado.
maio 22nd, 2014 16:29
Galera, pra vocês que estão com problemas nas anotações,
vá em
> Window -> Preferences -> Validation, JPA Validator
deixe o JPA Validator como off no checkbox.