Você está na página 1de 17

Tutorial - JPA 2.

0 com EclipseLink
Ricardo Ramos de Oliveira 7250 50 !niversidade de "#o Paulo $%&'&-!"P( JPA com EclipseLink Este tutorial explica como usar o EclipseLink, a implementao de referncia para a Java Persistence API (JPA) ! uso de EclipseLink " demonstrado para aplica#es Java stand$alone (fora do am%iente Java EE) ! EclipseLink implementao & ' x foi utili(ado para este tutorial )ndice *. JPA *.*. +is#o ,lo-al *.2. Entidade *. . Persist.ncia dos &ampos *./. 'apeamento de Relacionamento *.5. 0erenciador de Entidade *.1. !nidades de Persist.ncia 2. %nstala2#o 2.*. EclipseLink 2.2. 3anco de 4ados 4er-5 . E6emplo "imples .*. Pro7eto e Entidade .2. !nidade de persist.ncia . . Teste sua instala2#o /. E6emplo de Relacionamento 5. A,radecimentos 1. Per,untas e 4iscuss#o 7. Links e Literatura 7.*. Recursos da AP% Java Persistence 7.2. Recursos +o,ella

*. JPA
*.*. vis#o ,lo-al ! processo de mapeamento de o%)etos Java para ta%elas de %anco de dados e vice$versa " c*amada de +mapeamento o%)eto$relacional+ (!,-) A Java Persistence API (JPA) " uma a%orda.em para !,- /ia JPA o desenvolvedor pode mapear, arma(enar, atuali(ar e recuperar dados de %ancos de dados relacionais para o%)etos Java e vice$versa, JPA permite ao desenvolvedor tra%al*ar diretamente com o%)etos ao inv"s de instru#es 01L JPA " uma especificao e implementao entre v2rias dispon3veis Este tutorial ir2 usar EclipseLink como a implementao JPA A implementao JPA " normalmente c*amado fornecedor de persistncia JPA pode ser usado em Java EE e em aplica#es Java 0E

*.2. Entidade 4ma classe 5ue deve ser mantida em um %anco de dados deve ser anotada com +)avax persistence Entit6+ 7al classe " c*amada de entidade A JPA vai criar uma ta%ela para a entidade em seu %anco de dados As inst8ncias da classe corresponde a uma lin*a da ta%ela

7odas as classes de entidade devem definir uma c*ave prim2ria, deve ter um construtor sem ar.umentos e ou no ten*a permisso para ser final As c*aves podem ser um campo 9nico ou uma com%inao de campos JPA permite .erar automaticamente a c*ave prim2ria no %anco de dados atrav"s da anotao 8 0enerated+alue Por padro, o nome da ta%ela corresponde ao nome da classe /oc pode mudar isso adicionando a anotao 8 Ta-le $name 9 :;O'E4ATA3ELA:( *. . Persist.ncia dos &ampos !s campos da Entidade sero salvos no %anco de dados JPA pode usar suas vari2veis de inst8ncia (campos) ou o correspondente .etters e setters para acessar os campos /oc no tem permisso para misturar os dois m"todos 0e voc 5uiser usar os m"todos setter e .etter da classe Java deve se.uir as conven#es de nomenclatura Java :ean A JPA persisti por padro todos os campos de uma entidade, se os campos no devem ser .uardados devero ser assinaladas com a anotao 8 Transient Por padro cada campo " mapeado para uma coluna com o nome do campo /oc pode alterar o nome padro via 8&olumn $name 9 :;O'E;O+A&OL!;A:( As anota#es a se.uir pode ser usadas 8%d Identificador 9nico I; do %anco de dados 80enerated+alue Juntamente definido com o I; este valor ser2 .erado automaticamente 8Transient ! campo no ser2 salvo no %anco de dados Ta-ela *. Anota2<es para campos = ,etter e setter *./. 'apeamento de Relacionamento JPA permite definir relacionamentos entre as classes, por exemplo, pode ser definida uma classe 5ue fa( parte de outra classe (composio) As classes podem ter relacionamentos <$<, um para muitos, muitos para um, e muitos para muitos com outras classes A relao pode ser %idirecional ou unidirecional, por exemplo, em um relacionamento %idirecional am%as as classes arma(enam uma referncia de uma para a outra, en5uanto no caso unidirecional apenas uma classe tem uma referncia da outra classe ;entro de um relacionamento %idirecional voc precisa especificar o lado propriet2rio dessa relao na outra classe com o atri%uto +mapped:6+, por exemplo, 8 'an5To'an5 $mapped35 9 :ATR%3!TO&LA""EPROPR%ET>R%A:( 8OneToOne 8OneTo'an5 8'an5ToOne 8'an5To'an5 Ta-ela 2. Anota2<es de Relacionamentos

*.5. 0erenciador de entidade A entidade mana.er +)avax persistence Entit6-ana.er+ fornece as opera#es do %anco de dados, por exemplo, encontrar o%)etos, persisti$los, remover o%)etos do %anco de dados, etc Em uma aplicao JavaEE o .erenciador de entidades " automaticamente inserido na aplicao =e% >ora de uma aplicao JavaEE voc precisa .erenciar o .erenciador de entidades Entidades 5ue so .erenciadas por um ?erenciador de Entidade ir2 propa.ar automaticamente as altera#es e modifica#es para o %anco de dados (se isso acontecer dentro de uma instruo commit) 0e o ?erenciador de Entidade for fec*ado (via close ()), as entidades .erenciadas se encontram em estados separados Para sincroni(2$los novamente com o %anco de dados o ?erenciador de Entidade fornece o m"todo mer.e () ! contexto de persistncia descreve todas as Entidades de um .erenciador de entidades *.1. !nidades de persist.ncia ! Entit6-ana.er " criado pelo Entiti6-ana.er>actor6 5ue " confi.urado pela unidade de persistncia A unidade de persistncia " descrita atrav"s do ar5uivo +persistence xml+ no diret@rio -E7A$IA> na pasta de ori.em do pro)eto 4m con)unto de entidades lo.icamente conectadas, sero a.rupadas atrav"s de uma unidade de persistncia ! ar5uivo +persistence xml+ define os dados de conexo ao %anco de dados, por exemplo, o driver, o usu2rio e a sen*a

2. %nstala2#o
2.*. EclipseLink :aixar o ar5uivo instalador (ip da implementao do EclipseLink no linkB *ttpBCC=== eclipse or.CeclipselinkCdo=nloadsC ! do=nload cont"m v2rios )arDs Precisamos dos se.uintes )arsB

eclipselink )ar )avax persistenceEF )ar

2.2. 3anco de 4ados 4er-5 !s exemplos a se.uir utili(am o Apac*e ;er%6 como %anco de dados ! do=nload do ;er%6 pode ser feito atrav"s do linkB *ttpBCCd% apac*e or.Cder%6C A partir deste tutorial vamos precisar do +der%6 )ar+ Para mais detal*es so%re ;er%6 (5ue no " necess2rio para este tutorial) consulte Apac*e ;er%6

. E6emplo simples
.*. Pro7eto e Entidade Grie um pro)eto Java +de vo.ella )pa simple+ Grie uma pasta +li%+ e colo5ue os )arDs necess2rios da JPA e o der%6 )ar nesta pasta Adicionar as %i%liotecas ao classpat* do pro)eto ;epois de criar o pacote +de vo.ella )pa simple model+ e criar as se.uintes classes
@Entity public class Todo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String summary; private String description; public String getSummary() { return summary; } public void setSummary(String summary) { this.summary = summary; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Override public String toString() { return "Todo [summary=" + summary + ", description=" + description + "]"; } }

.2. !nidade de Persist.ncia Grie um diret@rio +-E7A$IA>+ na sua pasta +src+ e crie o ar5uivo +persistence xml+ Este exemplos utili(a atri%utos espec3ficos do EclipseLink, por exemplo, atrav"s do par8metro + eclipselink ddl$.eneration+ voc pode especificar 5ue o es5uema de %anco de dados ser2 automaticamente exclu3do e criado

<?xml version="1.0" encoding="UTF-8" ?> <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" version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">

<persistence-unit name="todos" transaction-type="RESOURCE_LOCAL"> <class>de.vogella.jpa.simple.model.Todo</class> <properties> <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" /> <property name="javax.persistence.jdbc.url"

value="jdbc:derby:/home/vogella/databases/simpleDb;create=true /> <property name="javax.persistence.jdbc.user" value="test" /> <property name="javax.persistence.jdbc.password" value="test" /> <!-- EclipseLink should create the database schema automatically --> <property name="eclipselink.ddl-generation" value="create-tables" /> <property name="eclipselink.ddl-generation.output-mode" value="database" /> </properties> </persistence-unit> </persistence>

! %anco de dados especificado via +)avax persistence )d%c url+ ser2 criado automaticamente pelo driver ;er%6 /oc pode 5uerer a)ustar o pat*, 5ue atualmente " %aseado em nota#es Linux e aponta para o diret@rio *ome no sistema Linux Para ver o 01L .erado para as %ases de dados o con)unto eclipselink ddl$ .eneration output modo de valor a partir de +%anco de dados+ para +s5l$script+ ou +am%as+ ;ois ar5uivos sero .erados +create;;L )d%c HeH drop;;L )d%cH . . Teste sua %nstala2#o Grie a se.uinte classe -ain )ava na 5ual criar2 uma nova entrada sempre 5ue for executada Ap@s a primeira c*amada " necess2rio remover a propriedade +eclipselink ddl$.eneration+ de persistence xml caso contr2rio, voc rece%er2 um erro do EclipseLink como tentar criar o es5uema de %anco de dados novamente 4ma

alternativa 5ue voc poderia definir a propriedade como +drop$and$create$ta%les+ mas isso iria apa.ar o seu es5uema de %anco de dados em cada execuo
package de.vogella.jpa.simple.main; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.persistence.Query; import de.vogella.jpa.simple.model.Todo;

public class Main { private static final String PERSISTENCE_UNIT_NAME = "todos"; private static EntityManagerFactory factory;

public static void main(String[] args) { factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); EntityManager em = factory.createEntityManager(); // Read the existing entries and write to console Query q = em.createQuery("select t from Todo t"); List<Todo> todoList = q.getResultList(); for (Todo todo : todoList) { System.out.println(todo); } System.out.println("Size: " + todoList.size());

// Create new todo em.getTransaction().begin(); Todo todo = new Todo(); todo.setSummary("This is a test"); todo.setDescription("This is a test"); em.persist(todo); em.getTransaction().commit();

em.close(); } }

Execute o seu pro.rama v2rias ve(es para ver 5ue o %anco de dados " preenc*ido

/. E6emplo de Relacionamento
Grie um pro)eto Java +de vo.ella )pa eclipselink+, crie novamente uma pasta +li%+ e colo5ue os )arDs necess2rios do JPA e o der%6 )ar nesta pasta Adicione as %i%liotecas ao classpat* do pro)eto Griar o pacote +de vo.ella )pa eclipselink model+ e as se.uintes classes
package de.vogella.jpa.eclipselink.model;

import java.util.ArrayList; import java.util.List;

import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany;

@Entity public class Family { @Id @GeneratedValue(strategy = GenerationType.TABLE) private int id; private String description;

@OneToMany(mappedBy = "family") private final List<Person> members = new ArrayList<Person>();

public int getId() { return id; }

public void setId(int id) { this.id = id; }

public String getDescription() { return description; }

public void setDescription(String description) {

this.description = description; }

public List<Person> getMembers() { return members; }

package de.vogella.jpa.eclipselink.model;

import java.util.ArrayList; import java.util.List;

import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.Transient;

@Entity public class Person { @Id @GeneratedValue(strategy = GenerationType.TABLE) private String id; private String firstName; private String lastName;

private Family family;

private String nonsenseField = "";

private List<Job> jobList = new ArrayList<Job>();

public String getId() { return id; }

public void setId(String Id) {

this.id = Id; }

public String getFirstName() { return firstName; }

public void setFirstName(String firstName) { this.firstName = firstName; }

// Leave the standard column name of the table public String getLastName() { return lastName; }

public void setLastName(String lastName) { this.lastName = lastName; }

@ManyToOne public Family getFamily() { return family; }

public void setFamily(Family family) { this.family = family; }

@Transient public String getNonsenseField() { return nonsenseField; }

public void setNonsenseField(String nonsenseField) { this.nonsenseField = nonsenseField; }

@OneToMany public List<Job> getJobList() { return this.jobList;

public void setJobList(List<Job> nickName) { this.jobList = nickName; }

package de.vogella.jpa.eclipselink.model;

import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id;

@Entity public class Job { @Id @GeneratedValue(strategy = GenerationType.TABLE) private int id; private double salery; private String jobDescr;

public int getId() { return id; }

public void setId(int id) { this.id = id; }

public double getSalery() { return salery; }

public void setSalery(double salery) { this.salery = salery; }

public String getJobDescr() { return jobDescr;

public void setJobDescr(String jobDescr) { this.jobDescr = jobDescr; }

Grie o ar5uivo +persistence xml+ em +src C -E7A$IA>+ Lem%re$se de mudar o camin*o para o %anco de dados

<?xml version="1.0" encoding="UTF-8" ?> <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" version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"> <persistence-unit name="people" transactiontype="RESOURCE_LOCAL">

<class>de.vogella.jpa.eclipselink.model.Person</class> <class>de.vogella.jpa.eclipselink.model.Family</class> <class>de.vogella.jpa.eclipselink.model.Job</class>

<properties> <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" /> <property name="javax.persistence.jdbc.url" value="jdbc:derby:/home/vogella/databases/relationsshipDb;create=true " /> <property name="javax.persistence.jdbc.user" value="test" /> <property name="javax.persistence.jdbc.password" value="test" /> <!-- EclipseLink should create the database schema automatically --> <property name="eclipselink.ddl-generation" value="create-tables" />

<property name="eclipselink.ddl-generation.output-mode" value="database" /> </properties> </persistence-unit> </persistence>

A seleo a se.uir " implementado como um teste J4nit Para mais informa#es consulte /e)a um 7utorial do J4nit ! m"todo setup () ir2 criar um ar5uivo de entradas de al.uns testes Ap@s as entradas de teste so criados, eles sero lidos e no campo uma das entradas " alterado e salvo no %anco de dados
package de.vogella.jpa.eclipselink.main;

import static org.junit.Assert.assertTrue;

import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.persistence.Query;

import org.junit.Before; import org.junit.Test;

import de.vogella.jpa.eclipselink.model.Family; import de.vogella.jpa.eclipselink.model.Person;

public class JpaTest {

private static final String PERSISTENCE_UNIT_NAME = "people"; private EntityManagerFactory factory;

@Before public void setUp() throws Exception { factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); EntityManager em = factory.createEntityManager();

// Begin a new local transaction so that we can persist a new entity em.getTransaction().begin();

// Read the existing entries

Query q = em.createQuery("select m from Person m"); // Persons should be empty

// Do we have entries? boolean createNewEntries = (q.getResultList().size() == 0);

// No, so lets create new entries if (createNewEntries) { assertTrue(q.getResultList().size() == 0); Family family = new Family(); family.setDescription("Family for the Knopfs"); em.persist(family); for (int i = 0; i < 40; i++) { Person person = new Person(); person.setFirstName("Jim_" + i); person.setLastName("Knopf_" + i); em.persist(person); // Now persists the family person relationship family.getMembers().add(person); em.persist(person); em.persist(family); } }

// Commit the transaction, which will cause the entity to // be stored in the database em.getTransaction().commit();

// It is always good practice to close the EntityManager so that // resources are conserved. em.close();

@Test public void checkAvailablePeople() {

// Now lets check the database and see if the created entries are there // Create a fresh, new EntityManager EntityManager em = factory.createEntityManager();

// Perform a simple query for all the Message entities Query q = em.createQuery("select m from Person m");

// We should have 40 Persons in the database assertTrue(q.getResultList().size() == 40);

em.close(); }

@Test public void checkFamily() { EntityManager em = factory.createEntityManager(); // Go through each of the entities and print out each of their // messages, as well as the date on which it was created Query q = em.createQuery("select f from Family f");

// We should have one family with 40 persons assertTrue(q.getResultList().size() == 1); assertTrue(((Family) q.getSingleResult()).getMembers().size() == 40); em.close(); }

@Test(expected = javax.persistence.NoResultException.class) public void deletePerson() { EntityManager em = factory.createEntityManager(); // Begin a new local transaction so that we can persist a new entity em.getTransaction().begin(); Query q = em .createQuery("SELECT p FROM Person p WHERE p.firstName = :firstName AND p.lastName = :lastName"); q.setParameter("firstName", "Jim_1"); q.setParameter("lastName", "Knopf_!");

Person user = (Person) q.getSingleResult(); em.remove(user); em.getTransaction().commit(); Person person = (Person) q.getSingleResult(); // Begin a new local transaction so that we can persist a new entity

em.close(); } }

! pro)eto a.ora deve ser semel*ante ao se.uinte

/oc deve ser capa( de executar com sucesso os testes J4nit

5. A,radecimentos
*ttpBCC=== icmc usp %rCIricardoramosC

1. Per,untas e 4iscuss#o
Antes de postar per.untas, consulte o >A1 *ttpBCC=== icmc usp %rCIricardoramosC 0e voc tiver d9vidas ou encontrar um erro neste arti.o, por favor envie um e$mail paraB ricardoramos uspJ.mail com

7. Links e Literatura
7.*. Java Persistence AP% Recursos *ttpBCC=== eclipse or.CeclipselinkC EclipseLink *ttpBCC)ava sun comCdeveloperCtec*nicalArticlesCJ&0EC;esktopCpersistenceapiC 4sando o Java Persistence API em aplica#es desktop *ttpBCC=== i%m comCdeveloper=orksC)avaCli%rar6C)$t6pesafe)paCindex *tml din8mico, consultas t6pesafe em JPA & K usando a API Griteria 7.2. vo,ella Recursos Eclipse ,GP 7reinamento Junte$se a min*a formao Eclipse ,GP para se tornar um especialista ,GP em L dias (>ormao em alemo) Android tutorial de introduo ao Android Pro.ramao ?M7 Pro.rama 7utorial em Java e compilar para Java0cript e N7-L Eclipse ,GP 7utorial criar aplicativos nativos em Java J4nit 7utorial 7este o seu aplicativo ?it 7utorial Golo5ue tudo 5ue voc tem so% o sistema de controle de verso distri%u3do

Você também pode gostar