Escolar Documentos
Profissional Documentos
Cultura Documentos
TutorialJPA
TutorialJPA
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 &os *./. '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 &os !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
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 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;
this.description = description; }
package de.vogella.jpa.eclipselink.model;
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;
this.id = Id; }
// Leave the standard column name of the table public String getLastName() { return lastName; }
package de.vogella.jpa.eclipselink.model;
@Entity public class Job { @Id @GeneratedValue(strategy = GenerationType.TABLE) private int id; private double salery; private String 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">
<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" />
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;
@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();
// 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();
// 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");
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(); } }
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