k19 k21 persistencia com jpa2 e hibernate

Upload: bruno-cassio

Post on 12-Oct-2015

25 views

Category:

Documents


0 download

TRANSCRIPT

  • TREINAMENTOS

    Persistncia comJPA2 e Hibernate

  • Persistncia com JPA 2 e Hibernate

    18 de junho de 2012

    Sumrio i

    Sobre a K19 1

    Seguro Treinamento 2

    Termo de Uso 3

    Cursos 4

    1 Introduo 11.1 Persistncia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Configurao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.3 Mapeamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21.4 Gerando o banco . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.5 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.6 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.7 Manipulando entidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.8 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.9 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

    2 Mapeamento 92.1 Entidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.2 Definindo Restries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.3 Gerando chaves primrias automaticamente . . . . . . . . . . . . . . . . . . . . . . . . . 102.4 Mapeamento Automtico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.5 Objetos Grandes (LOB) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.6 Data e Hora . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.7 Dados Transientes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.8 Field Access e Property Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.9 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142.10 Enums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.11 Colees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162.12 Relacionamentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

    www.k19.com.br i

  • SUMRIO ii

    2.13 One to One . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182.14 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202.15 One to Many . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.16 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232.17 Many to One . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252.18 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262.19 Many to Many . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282.20 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292.21 Relacionamentos Bidirecionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312.22 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322.23 Objetos Embutidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342.24 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362.25 Herana . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372.26 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

    3 Entity Manager 433.1 Estados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433.2 Sincronizao com o Banco de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433.3 Transies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453.4 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463.5 LAZY e EAGER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503.6 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533.7 Caching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563.8 Persistence Context ou Cache de Primeiro Nvel . . . . . . . . . . . . . . . . . . . . . . . 563.9 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 573.10 Shared Cache ou Cache de Segundo Nvel . . . . . . . . . . . . . . . . . . . . . . . . . . . 573.11 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583.12 Cascade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593.13 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 613.14 Remoo de Objetos rfos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623.15 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 633.16 Callbacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663.17 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 683.18 Concorrncia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 693.19 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703.20 Locking Otimista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713.21 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 723.22 Locking Pessimista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 723.23 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

    4 JPQL 754.1 Consultas Dinmicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 754.2 Named Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 754.3 Parmetros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 764.4 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 774.5 Tipos de Resultado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 814.6 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 844.7 Paginao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 884.8 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 884.9 O Problema do N +1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

    ii www.k19.com.br

  • iii SUMRIO

    4.10 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 894.11 Operaes em Lote (Bulk Operations) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 904.12 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 914.13 Operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 934.14 Exemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 974.15 Referncias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 984.16 Consultas Nativas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 984.17 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

    5 Criteria 1015.1 Necessidade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1015.2 Estrutura Geral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1015.3 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1025.4 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1055.5 Tipos de Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1055.6 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1075.7 Filtros e Predicados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1095.8 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1095.9 Lista de Predicados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1095.10 Funes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1125.11 Ordenao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1145.12 Subqueries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1145.13 Exemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1145.14 O Problema do N +1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1165.15 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1175.16 Metamodel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1185.17 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

    A Hibernate Search 123A.1 Configurao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123A.2 Mapeamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124A.3 Indexao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124A.4 Busca . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124A.5 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125

    B Hibernate Envers 129B.1 Mapeamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129B.2 Consultas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130B.3 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130

    C Bean Validation e Hibernate Validator 135C.1 Regras de Validao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135C.2 Processando as Validaes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136C.3 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137

    D Mapeamento com XML 141D.1 Entidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141D.2 Definindo Restries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143D.3 Gerando chaves primrias automaticamente . . . . . . . . . . . . . . . . . . . . . . . . . 144D.4 Mapeamento Automtico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144

    www.k19.com.br iii

  • SUMRIO iv

    D.5 Objetos Grandes (LOB) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145D.6 Data e Hora . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145D.7 Dados Transientes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146D.8 Field Access e Property Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147D.9 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147D.10 Enums . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149D.11 Colees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150D.12 Relacionamentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152D.13 One to One . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153D.14 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155D.15 One to Many . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156D.16 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159D.17 Many to One . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160D.18 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163D.19 Many to Many . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164D.20 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166D.21 Relacionamentos Bidirecionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167D.22 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170D.23 Objetos Embutidos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172D.24 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174D.25 Herana . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176D.26 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180

    E Respostas 183

    iv www.k19.com.br

  • 1 SUMRIO

    Sobre a K19

    A K19 uma empresa especializada na capacitao de desenvolvedores de software. Sua equipe composta por profissionais formados em Cincia da Computao pela Universidade de So Paulo(USP) e que possuem vasta experincia em treinamento de profissionais para rea de TI.

    O principal objetivo da K19 oferecer treinamentos de mxima qualidade e relacionados s prin-cipais tecnologias utilizadas pelas empresas. Atravs desses treinamentos, seus alunos se tornamcapacitados para atuar no mercado de trabalho.

    Visando a mxima qualidade, a K19 mantm as suas apostilas em constante renovao e melho-ria, oferece instalaes fsicas apropriadas para o ensino e seus instrutores esto sempre atualizadosdidtica e tecnicamente.

    www.k19.com.br 1

  • SUMRIO 2

    Seguro Treinamento

    Na K19 o aluno faz o curso quantas vezes quiser!

    Comprometida com o aprendizado e com a satisfao dos seus alunos, a K19 a nica que pos-sui o Seguro Treinamento. Ao contratar um curso, o aluno poder refaz-lo quantas vezes desejarmediante a disponibilidade de vagas e pagamento da franquia do Seguro Treinamento.

    As vagas no preenchidas at um dia antes do incio de uma turma da K19 sero destinadas aoalunos que desejam utilizar o Seguro Treinamento. O valor da franquia para utilizar o Seguro Treina-mento 10% do valor total do curso.

    2 www.k19.com.br

  • 3 SUMRIO

    Termo de Uso

    Termo de Uso

    Todo o contedo desta apostila propriedade da K19 Treinamentos. A apostila pode ser utilizadalivremente para estudo pessoal . Alm disso, este material didtico pode ser utilizado como materialde apoio em cursos de ensino superior desde que a instituio correspondente seja reconhecida peloMEC (Ministrio da Educao) e que a K19 seja citada explicitamente como proprietria do material.

    proibida qualquer utilizao desse material que no se enquadre nas condies acima semo prvio consentimento formal, por escrito, da K19 Treinamentos. O uso indevido est sujeito smedidas legais cabveis.

    www.k19.com.br 3

  • SUMRIO 4

    K01- Lgica de Programao

    K11 - Orientao a Objetos em Java

    K12 - Desenvolvimento Web com JSF2 e JPA2

    K21 - Persistncia com JPA2 e Hibernate

    K22 - Desenvolvimento Web Avanado com JFS2, EJB3.1 e CDI

    K23 - Integrao de Sistemas com Webservices, JMS e EJB

    K31 - C# e Orientao a Objetos

    K32 - Desenvolvimento Web com ASP.NET MVC

    TREINA

    MENT

    OS

    TREINAMENTOSTREINAMENTOS Conhea os nossos cursos

    www.k19.com.br/cursos

    4 www.k19.com.br

  • INTRODUO

    CA

    P

    TU

    LO

    1Persistncia

    Aplicaes corporativas manipulam dados em grande quantidade. Na maioria dos casos, essesdados so armazenados em bancos de dados relacionais, pois os principais sistemas gerenciadoresde bancos de dados do mercado utilizam o modelo relacional. Por outro lado, hoje em dia, as aplica-es corporativas costumam ser desenvolvidas com linguagens orientadas a objetos.

    Como o modelo relacional e o modelo orientado a objetos diferem no modo de estruturar osdados, uma transformao deve ocorrer toda vez que alguma informao trafegar da aplicao parao banco de dados ou vice-versa. Essa transformao no simples, pois os dois modelos so bemdiferentes.

    No contexto das aplicaes Java, para facilitar o processo de transformao dos dados que trafe-gam entre as aplicaes e os bancos de dados, podemos utilizar algumas ferramentas de persistnciacomo o Hibernate ou o EclipseLink.

    Essas ferramentas funcionam como intermedirios entre as aplicaes e os bancos de dados,automatizando diversos processos importantes relacionados persistncia dos dados. Elas so cha-madas de ferramentas ORM (Object Relational Mapping).

    Com o intuito de facilitar a utilizao dessas ferramentas e torn-las compatveis com os outrosrecursos da plataforma Java, elas so padronizadas pela especificao Java Persistence API (JPA).

    Veremos, nesse captulo, os passos principais para utilizar uma implementao da JPA. Em par-ticular, utilizaremos o Hibernate e o sistema gerenciador de banco de dados MySQL.

    Configurao

    Antes de comear a utilizar o Hibernate, necessrio baixar do site oficial o bundle que inclui osjars do hibernate e todas as suas dependncias. Neste curso, utilizaremos a verso 4.1.2. A url do siteoficial do Hibernate http://www.hibernate.org/.

    Mais SobreVeja tambm um artigo da K19 sobre configurao do Hibernate no seguinte endereohttp://www.k19.com.br/artigos/configurando-hibernate-com-mysql/.

    Para configurar o Hibernate em uma aplicao, devemos criar um arquivo chamado persisten-ce.xml. O contedo desse arquivo contm informaes sobre o banco de dados, como a url de cone-

    www.k19.com.br 1

  • INTRODUO 2

    xo, usurio e senha, alm de dados sobre a implementao JPA que ser utilizada.

    O arquivo persistence.xml deve ser salvo em uma pasta chamada META-INF, que deve estarno classpath da aplicao. Veja abaixo um exemplo de configurao para o persistence.xml:

    1 67 8 org.hibernate.ejb.HibernatePersistence 9 10 12 13 14 15 16 17 19 20 21

    Cdigo XML 1.1: persistence.xml

    Mapeamento

    Um dos principais objetivos dos frameworks ORM estabelecer o mapeamento entre os concei-tos do modelo orientado a objetos e os conceitos do modelo relacional. Este mapeamento pode serdefinido atravs de xml ou de maneira mais prtica com anotaes Java. Quando utilizamos anota-es, evitamos a criao de extensos arquivos em xml.

    A seguir, veremos as principais anotaes Java de mapeamento do JPA. Essas anotaes esto nopacote javax.persistence.

    @Entity a principal anotao do JPA. Ela deve aparecer antes do nome de uma classe e deve serdefinida em todas as classes que tero objetos persistidos no banco de dados.

    As classes anotadas com @Entity so mapeadas para tabelas. Por conveno, as tabelas pos-suem os mesmos nomes das classes. Mas, podemos alterar esse comportamento utilizando aanotao @Table.

    Os atributos declarados em uma classe anotada com @Entity so mapeados para colunas natabela correspondente classe. Outra vez, por conveno, as colunas possuem os mesmos no-mes dos atributos. E novamente, podemos alterar esse padro utilizando para isso a anotao@Column.

    @Id utilizada para indicar qual atributo de uma classe anotada com @Entity ser mapeado paraa chave primria da tabela correspondente classe. Geralmente o atributo anotado com @Id do tipo Long.

    2 www.k19.com.br

  • 3 INTRODUO

    @GeneratedValue Geralmente vem acompanhado da anotao @Id. Serve para indicar que o valorde um atributo que compe uma chave primria deve ser gerado pelo banco no momento emque um novo registro inserido.

    Gerando o banco

    Uma das vantagens de utilizar uma implementao JPA que ela capaz de gerar as tabelas nobanco de dados. Ela faz isso de acordo com as anotaes colocadas nas classes e as informaespresentes no arquivo persistence.xml.

    As tabelas so geradas atravs de um mtodo esttico da classe Persistence, o createEntity-ManagerFactory(string persistenceUnit). O parmetro persistenceUnitpermite escolher, pelonome, uma unidade de persistncia definida no persistence.xml.

    1 Persistence.createEntityManagerFactory("K19 -PU");

    Cdigo Java 1.1: Inicializando uma unidade de persistncia.

    Exerccios de Fixao

    1 Para apresentar os conceitos bsicos de JPA, implementaremos parte de um sistema de gerenci-amento de uma livraria. Primeiramente, crie um projeto no Eclipse chamado K19-JPA2-Hibernate.

    2 Crie uma pasta chamada lib dentro do projeto K19-JPA2-Hibernate.

    3 Entre na pasta K19-Arquivos/hibernate-release-4.1.2.Final/lib da rea de Trabalho e copie osjars da pasta required e da pasta jpa para a pasta lib do projeto K19-JPA2-Hibernate.

    4 Entre na pasta K19-Arquivos/MySQL-Connector-JDBC da rea de Trabalho e copie o arquivomysql-connector-java-5.1.19.bin.jar para pasta lib do projeto K19-JPA2-Hibernate.

    5 Adicione os jars da pasta lib ao build path do projeto K19-JPA2-Hibernate. Pea orientao doinstrutor se for necessrio.

    6 Crie uma pasta chamada META-INF dentro da pasta src do projeto K19-JPA2-Hibernate.

    7 Crie o arquivo de configuraes persistence.xml na pasta META-INF. Para no ter de digitar todoo cdigo, copie o modelo persistence.xml da pasta K19-Arquivos/modelos da sua rea de Trabalho.Altere esse modelo de acordo com o cdigo abaixo.

    1 67 8 org.hibernate.ejb.HibernatePersistence 9 10 12

    www.k19.com.br 3

  • INTRODUO 4

    13 14 16 17 18 20 21 22

    Cdigo XML 1.2: persistence.xml

    8 Crie uma classe para modelar as editoras da nossa livraria e acrescente as anotaes necessriaspara fazer o mapeamento. Essas anotaes devem ser importadas do pacote javax.persistence.Adicione essa classe em um pacote chamado br.com.k19.modelo.

    1 @Entity2 public class Editora {3 @Id @GeneratedValue4 private Long id;56 private String nome;78 private String email;910 // GETTERS E SETTERS11 }

    Cdigo Java 1.2: Editora.java

    9 Apague a base dados K21_livraria_bd se ela existir atravs do MySQL Workbench. Pea orienta-o do instrutor se for necessrio.

    10 Crie a base dados K21_livraria_bd atravs do MySQL Workbench. Pea orientao do instrutorse for necessrio.

    11 Gere as tabelas usando o mtodo createEntityManagerFactory() da classe Persistence. Paraisso, crie uma classe com mtodo main em um pacote chamado br.com.k19.testes no projeto K19-JPA2-Hibernate. Obs: As classes devem ser importadas do pacote javax.persistence.

    1 public class GeraTabelas {2 public static void main(String [] args) {3 EntityManagerFactory factory =4 Persistence.createEntityManagerFactory("K21_livraria_pu");56 factory.close();7 }8 }

    Cdigo Java 1.3: GeraTabelas.java

    Execute e verifique atravs do MySQL Workbench se a tabela Editora foi criada corretamente.

    Exerccios Complementares

    1 Na pacote br.com.k19.modelo do projeto K19-JPA2-Hibernate, crie uma classe chamada Autorpara modelar um autor. Essa classe deve conter dois atributos: um para armazenar o id do autor e

    4 www.k19.com.br

  • 5 INTRODUO

    outra para armazenar o nome do autor.

    2 Gere novamente as tabelas da base de dados K19_livraria_bd usando o mtodo create-EntityManagerFactory() da classe Persistence. Atravs do MySQL Workbench, verifique se a ta-bela Autor foi criada corretamente.

    Manipulando entidades

    Para manipular as entidades da nossa aplicao, devemos utilizar um EntityManager que ob-tido atravs de uma EntityManagerFactory.

    1 EntityManagerFactory factory =2 Persistence.createEntityManagerFactory("K19 -PU");34 EntityManager manager = factory.createEntityManager ();

    Cdigo Java 1.6: Obtendo um Entity Manager

    Persistindo

    Para armazenar as informaes de um objeto no banco de dados, devemos utilizar o mtodopersist() do EntityManager.

    1 Editora novaEditora = new Editora ();2 novaEditora.setNome("K19 - Livros")3 novaEditora.setEmail("[email protected]");45 manager.persist(novaEditora);

    Cdigo Java 1.7: Associando um objeto a um Entity Manager.

    Buscando

    Para obter um objeto que contenha informaes do banco de dados, podemos utilizar os mto-dos find() ou getReference() do EntityManager.

    1 Editora editora1 = manager.find(Editora.class , 1L);2 Editora editora2 = manager.getReference(Editora.class , 2L);

    Cdigo Java 1.8: Buscando objetos.

    H uma diferena entre esses mtodos de busca. O mtodo find() recupera os dados desejadosimediatamente. J o mtodo getReference() posterga essa tarefa at a primeira chamada de ummtodo get no objeto desejado.

    Removendo

    Para remover um registro correspondente a um objeto, podemos utilizar o mtodo remove() doEntityManager.

    www.k19.com.br 5

  • INTRODUO 6

    1 Editora editora = manager.find(Editora.class , 1L);2 manager.remove(editora);

    Cdigo Java 1.9: Marcando um objeto para ser removido.

    Atualizando

    Para alterar os dados de um registro correspondente a um objeto, podemos utilizar os prpriosmtodos setters desse objeto.

    1 Editora editora = manager.find(Editora.class , 1L);2 editora.setNome("K19 - Livros e Publicaes");

    Cdigo Java 1.10: Alterando o contedo de um objeto.

    Listando

    Para obter uma listagem com todos os objetos referentes aos registros de uma tabela, podemosutilizar a linguagem de consulta do JPA, a JPQL. Essa linguagem muito parecida com a linguagemSQL. A vantagem da JPQL em relao linguagem SQL que a sintaxe a mesma para bancos dedados diferentes.

    1 Query query = manager.createQuery("SELECT e FROM Editora e");2 List editoras = query.getResultList ();

    Cdigo Java 1.11: Definindo e executando uma consulta JPQL.

    Transaes

    As modificaes realizadas nos objetos administrados por um EntityManager so mantidas emmemria. Em certos momentos, necessrio sincronizar os dados da memria com os dados dobanco de dados. Essa sincronizao deve ser realizada atravs de uma transao JPA criada peloEntityManager que administra os objetos que desejamos sincronizar.

    Para abrir uma transao utilizamos o mtodo begin().

    1 manager.getTransaction ().begin();

    Cdigo Java 1.12: Abrindo uma transao.

    Com a transao aberta, podemos sincronizar os dados com o banco atravs dos mtodos flush()(parcialmente) ou commit() (definitivamente).

    1 Editora editora = manager.find(Editora.class , 1L);2 editora.setNome("K19 - Livros e Publicaes");34 manager.getTransaction ().begin();5 manager.flush();

    Cdigo Java 1.13: Sincronizando parcialmente uma transao.

    6 www.k19.com.br

  • 7 INTRODUO

    1 Editora editora = manager.find(Editora.class , 1L);2 editora.setNome("K19 - Livros e Publicaes");34 manager.getTransaction ().begin();5 manager.getTransaction ().commit ();

    Cdigo Java 1.14: Sincronizando definitivamente uma transao

    Exerccios de Fixao

    12 No pacote br.com.k19.testes do projeto K19-JPA2-Hibernate, crie um teste para inserir edi-toras no banco de dados.

    1 public class InsereEditoraComJPA {23 public static void main(String [] args) {4 EntityManagerFactory factory =5 Persistence.createEntityManagerFactory("K21_livraria_pu");67 EntityManager manager = factory.createEntityManager ();89 Editora novaEditora = new Editora ();1011 Scanner entrada = new Scanner(System.in);1213 System.out.println("Digite o nome da editora: ");14 novaEditora.setNome(entrada.nextLine ());1516 System.out.println("Digite o email da editora: ");17 novaEditora.setEmail(entrada.nextLine ());1819 manager.persist(novaEditora);2021 manager.getTransaction ().begin();22 manager.getTransaction ().commit ();2324 factory.close();25 }26 }

    Cdigo Java 1.15: InsereEditoraComJPA.java

    13 No pacote br.com.k19.testes do projeto K19-JPA2-Hibernate, crie um teste para listar as edi-toras inseridas no banco de dados. No cdigo abaixo, a interface Query deve ser importada do pacotejavax.persistence e a interface List do pacote java.util.

    1 public class ListaEditorasComJPA {23 public static void main(String [] args) {4 EntityManagerFactory factory =5 Persistence.createEntityManagerFactory("K21_livraria_pu");67 EntityManager manager = factory.createEntityManager ();89 Query query = manager.createQuery("SELECT e FROM Editora e");10 List editoras = query.getResultList ();1112 for(Editora e : editoras) {13 System.out.println("EDITORA: " + e.getNome () + " - " + e.getEmail ());14 }15 }

    www.k19.com.br 7

  • INTRODUO 8

    16 }

    Cdigo Java 1.16: ListaEditorasComJPA.java

    Exerccios Complementares

    3 No pacote br.com.k19.testes do projeto K19-JPA2-Hibernate, crie um teste para inserir auto-res no banco de dados.

    4 No pacote br.com.k19.testes do projeto K19-JPA2-Hibernate, crie um teste para listar osautores inseridos no banco de dados.

    8 www.k19.com.br

  • MAPEAMENTO

    CA

    P

    TU

    LO

    2O mapeamento objeto-relacional o corao do Hibernate e das outras implementaes de JPA.

    Ele define quais transformaes devem ser realizadas nos dados para que essas informaes possamnavegar da aplicao para o banco de dados ou do banco de dados para a aplicao. Em particular, omapeamento determina como a ferramenta ORM far consultas complexas envolvendo mais do queuma tabela.

    Entidades

    As classes da nossa aplicao que devem ser mapeadas para tabelas do banco de dados so ano-tadas com @Entity. Cada instncia de uma classe anotada com @Entity deve possuir um identifica-dor nico. Em geral, esse identificador um atributo numrico que deve ser anotado com @Id.

    1 @Entity2 class Pessoa {3 @Id4 private Long id;5 }

    Cdigo Java 2.1: Pessoa.java

    Por conveno, a classe Pessoa ser mapeada para uma tabela com o mesmo nome (Pessoa). Oatributo id ser mapeado para uma coluna com o mesmo nome (id) na tabela Pessoa. As anotaes@Table e @Column podem ser usadas para personalizar os nomes das tabelas e das colunas.

    A coluna correspondente ao atributo id ser definida como chave primria da tabela Pessoadevido a presena da anotao @Id.

    1 @Entity2 @Table(name = "tbl_pessoas")3 class Pessoa {4 @Id5 @Column(name = "col_id")6 private Long id;7 }

    Cdigo Java 2.2: Pessoa.java

    www.k19.com.br 9

  • MAPEAMENTO 10

    (a) (b)

    Figura 2.1: Tabelas correspondentes classe Pessoa. Em (a), os nomes da tabela e da coluna so padres. Em (b), esses nomes so persona-lizados.

    Definindo Restries

    Podemos definir algumas restries para os atributos das nossas entidades atravs das proprie-dades da anotao @Column. Veja as principais propriedades abaixo:

    length Limita a quantidade de caracteres de uma stringnullable Determina se o campo pode possuir valores null ou nounique Determina se uma coluna pode ter valores repetidos ou noprecision Determina a quantidade de dgitos de um nmero decimal a serem armazenadasscale Determina a quantidade de casas decimais de um nmero decimal

    Tabela 2.1: Algumas propriedades da anotao @Column

    No exemplo a seguir, associamos trs restries ao atributo nome da classe Pessoa. O nome devepossuir no mximo 30 caracteres, no pode ser nulo e duas pessoas no podem ter o mesmo nome.Alm disso, definimos que a altura das pessoas ser representada por um nmero de trs dgitos,sendo dois deles referentes s casas decimais.

    1 @Entity2 class Pessoa {3 @Id4 private Long id;56 @Column(length =30, nullable=false ,unique=true)7 private String nome;89 @Column(precision=3,scale =2)10 private BigDecimal altura;11 }

    Cdigo Java 2.3: Pessoa.java

    Gerando chaves primrias automaticamente

    Em geral, os bancos de dados oferecem algum mecanismo para gerar os valores de uma chaveprimria simples e numrica. Do ponto de vista do desenvolvedor JPA, basta aplicar a anotao

    10 www.k19.com.br

  • 11 MAPEAMENTO

    @GeneratedValue para que o banco gere os valores de uma chave primria simples e numrica au-tomaticamente.

    1 @Entity2 class Pessoa {3 @Id4 @GeneratedValue5 private Long id;6 }

    Cdigo Java 2.4: Pessoa.java

    Mapeamento Automtico

    Cada banco possui o seu prprio conjunto de tipos de dados. Para que as informaes possamnavegar da aplicao para o banco e vice-e-versa, os tipos do Java devem ser mapeados para tiposapropriados do banco de dados.

    Alguns tipos do Java so mapeados automaticamente para tipos correspondentes do banco dedados. Eis uma lista dos tipos que so mapeados automaticamente:

    Tipos primitivos (byte, short, char, int, long, float, double e boolean)

    Classes Wrappers (Byte, Short, Character, Integer, Long, Float, Double e Boolean)

    String

    BigInteger e BigDecimal

    java.util.Date e java.util.Calendar

    java.sql.Date, java.sql.Time e java.sql.Timestamp

    Array de byte ou char

    Enums

    Serializables

    Esses tipos so chamados de tipos bsicos.

    Objetos Grandes (LOB)

    Eventualmente, dados maiores do que o comum devem ser armazenados no banco de dados.Por exemplo, uma imagem, uma msica ou um texto com muitas palavras. Para esses casos, osbancos de dados oferecem tipos de dados especficos. Do ponto de vista do desenvolvedor JPA, bastaaplicar a anotao @LOB (Large Objects) em atributos do tipo String, byte[], Byte[], char[] ouCharacter[] para que o provedor (Hibernate, EclipseLink ou outra implementao de JPA) utilize osprocedimentos adequados para manipular esses dados.

    www.k19.com.br 11

  • MAPEAMENTO 12

    1 @Entity2 class Pessoa {3 @Id4 @GeneratedValue5 private Long id;67 @Lob8 private byte[] avatar;9 }

    Cdigo Java 2.5: Pessoa.java

    Data e Hora

    Comumente, as aplicaes Java utilizam as classes java.util.Date e java.util.Calendar paratrabalhar com datas e horas. Essas classes so mapeadas automaticamente para tipos adequados nobanco de dados. Portanto, basta declarar os atributos utilizando um desses dois tipos nas classes quesero mapeadas para tabelas.

    1 @Entity2 class Pessoa {3 @Id4 @GeneratedValue5 private Long id;67 private Calendar nascimento;8 }

    Cdigo Java 2.6: Pessoa.java

    Por padro, quando aplicamos o tipo java.util.Date ou java.util.Calendar, tanto a dataquanto a hora sero armazenadas no banco de dados. Para mudar esse comportamento, devemosaplicar a anotao @Temporal escolhendo uma das trs opes abaixo:

    TemporalType.DATE: Armazena apenas a data (dia, ms e ano).

    TemporalType.TIME: Armazena apenas o horrio (hora, minuto e segundo).

    TemporalType.TIMESTAMP (Padro): Armazena a data e o horrio.

    1 @Entity2 class Pessoa {3 @Id4 @GeneratedValue5 private Long id;67 @Temporal(TemporalType.DATE)8 private Calendar nascimento;9 }

    Cdigo Java 2.7: Pessoa.java

    Dados Transientes

    12 www.k19.com.br

  • 13 MAPEAMENTO

    Eventualmente, no desejamos que alguns atributos de um determinado grupo de objetos sejampersistidos no banco de dados. Nesse caso, devemos aplicar o modificador transient ou a anotao@Transient.

    No exemplo abaixo, marcamos o atributo idade com a anotao @Transient para que essa infor-mao no seja armazenada no banco de dados. A idade de uma pessoa pode ser deduzida a partirde sua data de nascimento, que j est armazenada no banco.

    1 @Entity2 class Pessoa {3 @Id4 @GeneratedValue5 private Long id;67 @Temporal(TemporalType.DATE)8 private Calendar nascimento;910 @Transient11 private int idade;12 }

    Cdigo Java 2.8: Pessoa.java

    Figura 2.2: Tabela correspondente classe Pessoa. Note que essa tabela no possui nenhuma coluna associada ao atributo idade da classePessoa

    Field Access e Property Access

    Os provedores de JPA precisam ter acesso ao estado das entidades para poder administr-las.Por exemplo, quando persistimos uma instncia de uma entidade, o provedor deve pegar os da-dos desse objeto e armazen-los no banco. Quando buscamos uma instncia de uma entidade, oprovedor recupera as informaes correspondentes do banco de dados e guarda em um objeto.

    O JPA 2 define dois modos de acesso ao estado das instncias das entidades: Field Access e Pro-perty Access. Quando colocamos as anotaes de mapeamento nos atributos, estamos optando pelomodo Field Access. Por outro lado, tambm podemos colocar essas mesmas anotaes nos mtodosgetters. Nesse caso, estamos optando pelo modo Property Accesss.

    No modo Field Access, os atributos dos objetos so acessados diretamente atravs de reflectione no necessrio implementar mtodos getters e setters. Nesse modo de acesso, se os mtodosgetters e setters estiverem implementados, eles no sero utilizados pelo provedor JPA.

    No modo Property Access, os mtodos getters e setters devem necessariamente ser implementa-dos pelo desenvolvedor. Esses mtodos sero utilizados pelo provedor para que ele possa acessar emodificar o estado dos objetos.

    www.k19.com.br 13

  • MAPEAMENTO 14

    Exerccios de Fixao

    1 Crie um projeto no Eclipse chamado K19-Mapeamento. Copie a pasta lib do projeto K19-JPA2-Hibernate para o projeto K19-Mapeamento. Depois adicione os jars dessa pasta no classpath dessenovo projeto.

    2 Abra o MySQL Workbench e apague a base de dados K21_mapeamento_bd se existir. Depoiscrie a base de dados K21_mapeamento_bd.

    3 Copie a pasta META-INF do projeto K19-JPA2-Hibernate para dentro da pasta src do projetoK19-Mapeamento. Altere o arquivo persistence.xml do projeto K19-Mapeamento, modificando onome da unidade de persistncia e a base da dados. Veja como o cdigo deve ficar:

    1 67 8 org.hibernate.ejb.HibernatePersistence 9 10 12 13 14 16 17 18 20 21 22

    Cdigo XML 2.1: persistence.xml

    4 Crie uma entidade para modelar os usurios de uma rede social dentro de um pacote chamadobr.com.k19.modelo no projeto K19-Mapeamento.

    1 @Entity2 public class Usuario {3 @Id4 @GeneratedValue5 private Long id;67 @Column(unique=true)8 private String email;910 @Temporal(TemporalType.DATE)11 private Calendar dataDeCadastro;1213 @Lob14 private byte[] foto;1516 // GETTERS E SETTERS17 }

    Cdigo Java 2.9: Usuario.java

    14 www.k19.com.br

  • 15 MAPEAMENTO

    5 Adicione um usurio no banco de dados. Crie uma classe chamada AdicionaUsuario em umpacote chamado br.com.k19.testes no projeto K19-Mapeamento.

    1 public class AdicionaUsuario {2 public static void main(String [] args) {3 EntityManagerFactory factory =4 Persistence.createEntityManagerFactory("K21_mapeamento_pu");5 EntityManager manager = factory.createEntityManager ();67 manager.getTransaction ().begin();89 Usuario usuario = new Usuario ();10 usuario.setEmail("[email protected]");11 usuario.setDataDeCadastro(Calendar.getInstance ());1213 manager.persist(usuario);1415 manager.getTransaction ().commit ();1617 manager.close();18 factory.close();19 }20 }

    Cdigo Java 2.10: AdicionaUsuario.java

    6 Abra o MySQL Workbench e observe as propriedades da tabela Usuario da base de dadosK21_mapeamento_bd.

    Enums

    Por padro, os tipos enumerados de JAVA so mapeados para colunas numricas inteiras nobanco de dados. Cada elemento de um Enum associado a um nmero inteiro. Essa associao baseada na ordem em que os elementos do Enum so declarados. O primeiro elemento ser as-sociado ao valor 0, o segundo ser associado ao valor 1 e assim por diante. Considere o exemplo aseguir.

    1 @Entity2 public enum Periodo {3 MATUTINO ,4 NOTURNO5 }

    Cdigo Java 2.11: Periodo.java

    1 @Entity2 public class Turma {3 @Id4 @GeneratedValue5 private Long id;67 private Periodo periodo;8 }

    Cdigo Java 2.12: Turma.java

    O Enum Periodo possui dois elementos: MATUTINO e NOTURNO. O elemento MATUTINO ser associ-ado ao valor 0 e o elemento NOTURNO ser associado ao valor 1.

    www.k19.com.br 15

  • MAPEAMENTO 16

    A tabela correspondente classe Turma possuir um campo chamado periodo. Nos registroscorrespondentes s turmas de perodo matutino, esse campo possuir o valor 0. J nos registroscorrespondentes s turmas de perodo noturno, esse campo possuir o valor 1.

    Imagine que um novo perodo adicionado, digamos, o perodo vespertino. Nesse caso, o EnumPeriodo poderia vir a ser:

    1 @Entity2 public enum Periodo {3 MATUTINO ,4 VESPERTINO ,5 NOTURNO6 }

    Cdigo Java 2.13: Periodo.java

    Os valores j armazenados no banco de dados poderiam estar incorretos. Por exemplo, antesdessa modificao, o campo periodo das turmas noturnas deveria armazenar o valor 1. Aps essamodificao, o valor correto passa a ser 2. Assim, os valores do campo periodo da tabela Turmadevem ser atualizados de acordo. No entanto, essa atualizao no automtica, e deve ser feitamanualmente.

    Para evitar esse problema, podemos fazer com que os elementos de um Enum sejam associadosa uma string ao invs de um nmero inteiro. Isso pode ser feito com o uso da anotao @Enumerated.Observe o exemplo abaixo.

    1 @Entity2 public class Turma {3 @Id4 @GeneratedValue5 private Long id;67 @Enumerated(EnumType.STRING)8 private Periodo periodo;9 }

    Cdigo Java 2.14: Turma.java

    Nesse exemplo, os elementos MATUTINO, VESPERTINO e NOTURNO do Enum Periodo sero associa-dos s strings "MATUTINO", "VESPERTINO" e "NOTURNO", respectivamente.

    Colees

    Considere um sistema que controla o cadastro dos funcionrios de uma empresa. Esses funcio-nrios so modelados pela seguinte classe.

    1 @Entity2 public class Funcionario {34 @Id @GeneratedValue5 private Long id;67 private String nome;8 }

    Cdigo Java 2.15: Funcionario.java

    16 www.k19.com.br

  • 17 MAPEAMENTO

    Devemos tambm registrar os telefones de contato dos funcionrios, sendo que cada funcionriopode ter um ou mais telefones. Em Java, seria razovel utilizar colees para armazenar os telefonesdos funcionrios. Veja o exemplo abaixo.

    1 @Entity2 public class Funcionario {34 @Id @GeneratedValue5 private Long id;67 private String nome;89 @ElementCollection10 private Collection telefones;11 }

    Cdigo Java 2.16: Funcionario.java

    A anotao @ElementCollectiondeve ser utilizada para que o mapeamento seja realizado. Nesseexemplo, o banco de dados possuiria uma tabela chamada Funcionario_telefones contendo duascolunas. Uma coluna seria usada para armazenar os identificadores dos funcionrios e a outra paraos telefones. Veja uma ilustrao das tabelas do banco de dados na figura abaixo.

    Figura 2.3: Tabelas correspondentes classe Funcionario e ao atributo telefones

    A tabela criada para guardar os telefones dos funcionrios tambm pode ter o seu nome persona-lizado, assim como os nomes de suas colunas. Para isso, devemos aplicar as anotaes @Collection-Table e @Column.

    1 @Entity2 public class Funcionario {34 @Id @GeneratedValue5 private Long id;67 private String nome;89 @ElementCollection10 @CollectionTable(11 name="Telefones_dos_Funcionarios",12 joinColumns=@JoinColumn(name="func_id"))13 @Column(name="telefone")14 private Collection telefones;15 }

    Cdigo Java 2.17: Funcionario.java

    www.k19.com.br 17

  • MAPEAMENTO 18

    Figura 2.4: Personalizando os nomes da tabela e das colunas

    Relacionamentos

    Os relacionamentos entre as entidades de um domnio devem ser expressos na modelagem atra-vs de vnculos entre classes. De acordo com a JPA, podemos definir quatro tipos de relacionamentosde acordo com a cardinalidade.

    One to One (Um para Um): Por exemplo, um estado governado por apenas um governador e umgovernador governa apenas um estado.

    One to Many (Um para Muitos): Por exemplo, um departamento possui muitos funcionrios e umfuncionrio trabalha em apenas em um departamento.

    Many to One (Muitos para Um): Por exemplo, um pedido pertence a apenas um cliente e um clientefaz muitos pedidos.

    Many to Many (Muitos para Muitos): Por exemplo, um livro possui muitos autores e um autor pos-sui muitos livros.

    One to One

    Suponha que em nosso domnio existam duas entidades: Estado e Governador. Devemos criaruma classe para cada entidade e aplicar nelas as anotaes bsicas de mapeamento.

    18 www.k19.com.br

  • 19 MAPEAMENTO

    1 @Entity2 class Estado {3 @Id4 @GeneratedValue5 private Long id;6 }

    Cdigo Java 2.18: Estado.java

    1 @Entity2 class Governador {3 @Id4 @GeneratedValue5 private Long id;6 }

    Cdigo Java 2.19: Governador.java

    Como existe um relacionamento entre estados e governadores, devemos expressar esse vnculoatravs de um atributo que pode ser inserido na classe Estado.

    1 @Entity2 class Estado {3 @Id4 @GeneratedValue5 private Long id;67 private Governador governador;8 }

    Cdigo Java 2.20: Estado.java

    Alm disso, devemos informar ao provedor JPA que o relacionamento que existe entre um estadoe um governador do tipo One to One. Fazemos isso aplicando a anotao @OneToOne no atributoque expressa o relacionamento.

    1 @Entity2 class Estado {3 @Id4 @GeneratedValue5 private Long id;67 @OneToOne8 private Governador governador;9 }

    Cdigo Java 2.21: Estado.java

    No banco de dados, a tabela referente classe Estado possuir uma coluna de relacionamentochamada de join column. Em geral, essa coluna ser definida como uma chave estrangeira associada tabela referente classe Governador.

    Por padro, o nome da coluna de relacionamento formado pelo nome do atributo que esta-belece o relacionamento, seguido pelo caractere _ e pelo nome do atributo que define a chaveprimria da entidade alvo. No exemplo de estados e governadores, a join column teria o nome go-vernador_id.

    www.k19.com.br 19

  • MAPEAMENTO 20

    Figura 2.5: Tabelas correspondentes s classes Estado e Governador

    Podemos alterar o nome padro das join columns aplicando a anotao @JoinColumn, con-forme apresentado no exemplo abaixo.

    1 @Entity2 class Estado {3 @Id4 @GeneratedValue5 private Long id;67 @OneToOne8 @JoinColumn(name="gov_id")9 private Governador governador;10 }

    Cdigo Java 2.22: Estado.java

    Figura 2.6: Personalizando o nome da coluna de relacionamento

    Mais SobrePor padro, em um relacionamento One to One, um objeto da primeira entidade noprecisa estar necessariamente relacionado a um objeto da segunda entidade. Para exi-

    gir que cada objeto da primeira entidade esteja relacionado a um objeto da segunda entidade,devemos usar o atributo optional da anotao OneToOne.

    1 @Entity2 class Estado {3 @Id4 @GeneratedValue5 private Long id;67 @OneToOne(optional=false)8 private Governador governador;9 }

    Cdigo Java 2.23: Estado.java

    Exerccios de Fixao

    20 www.k19.com.br

  • 21 MAPEAMENTO

    7 Implemente duas entidades no pacote br.com.k19.modelo do projeto K19-Mapeamento: Es-tado e Governador.

    1 @Entity2 public class Governador {3 @Id4 @GeneratedValue5 private Long id;67 private String nome;89 // GETTERS E SETTERS10 }

    Cdigo Java 2.24: Governador.java

    1 @Entity2 public class Estado {3 @Id4 @GeneratedValue5 private Long id;67 private String nome;89 @OneToOne10 private Governador governador;1112 // GETTERS E SETTERS13 }

    Cdigo Java 2.25: Estado.java

    8 Adicione um governador e um estado no banco de dados. Crie uma classe chamada Adiciona-EstadoGovernador no pacote br.com.k19.testes do projeto K19-Mapeamento.

    1 public class AdicionaEstadoGovernador {2 public static void main(String [] args) {3 EntityManagerFactory factory =4 Persistence.createEntityManagerFactory("K21_mapeamento_pu");5 EntityManager manager = factory.createEntityManager ();67 manager.getTransaction ().begin();89 Governador g = new Governador ();10 g.setNome("Rafael Cosentino");1112 Estado e = new Estado ();13 e.setNome("So Paulo");14 e.setGovernador(g);1516 manager.persist(g);17 manager.persist(e);1819 manager.getTransaction ().commit ();2021 manager.close();22 factory.close();23 }24 }

    Cdigo Java 2.26: AdicionaEstadoGovernador.java

    9 Abra o MySQL Workbench e observe as propriedades das tabelas Estado e Governador da base

    www.k19.com.br 21

  • MAPEAMENTO 22

    de dados K21_mapeamento_bd.

    One to Many

    Suponha que em nosso domnio existam as entidades Departamento e Funcionrio. Criaramosduas classes com as anotaes bsicas de mapeamento.

    1 @Entity2 class Departamento {3 @Id4 @GeneratedValue5 private Long id;6 }

    Cdigo Java 2.27: Departamento.java

    1 @Entity2 class Funcionario {3 @Id4 @GeneratedValue5 private Long id;6 }

    Cdigo Java 2.28: Funcionario.java

    Como existe um relacionamento entre departamentos e funcionrios, devemos expressar essevnculo atravs de um atributo que pode ser inserido na classe Departamento. Supondo que umdepartamento possa ter muitos funcionrios, devemos utilizar uma coleo para expressar esse re-lacionamento.

    1 @Entity2 class Departamento {3 @Id4 @GeneratedValue5 private Long id;67 private Collection funcionarios;8 }

    Cdigo Java 2.29: Departamento.java

    Para informar a cardinalidade do relacionamento entre departamentos e funcionrios, devemosutilizar a anotao @OneToMany na coleo.

    1 @Entity2 class Departamento {3 @Id4 @GeneratedValue5 private Long id;67 @OneToMany8 private Collection funcionarios;9 }

    Cdigo Java 2.30: Departamento.java

    No banco de dados, alm das duas tabelas correspondentes s classes Departamento e Funciona-rio, deve existir uma terceira tabela para relacionar os registros dos departamentos com os registros

    22 www.k19.com.br

  • 23 MAPEAMENTO

    dos funcionrios. Essa terceira tabela chamada de tabela de relacionamento ou join table.

    Por padro, o nome da join table a concatenao com _ dos nomes das duas entidades. Noexemplo de departamentos e funcionrios, o nome do join table seria Departamento_Funcionario.Essa tabela possuir duas colunas vinculadas s entidades que formam o relacionamento. No exem-plo, a join table Departamento_Funcionario possuir uma coluna chamada Departamento_id e ou-tra chamada funcionarios_id.

    Figura 2.7: Tabelas correspondentes s classes Departamento e Funcionario

    Para personalizar os nomes das colunas da join table e da prpria join table, podemos aplicar aanotao @JoinTable no atributo que define o relacionamento.

    1 @Entity2 class Departamento {3 @Id4 @GeneratedValue5 private Long id;67 @OneToMany8 @JoinTable(name="DEP_FUNC",9 joinColumns=@JoinColumn(name="DEP_ID"),10 inverseJoinColumns=@JoinColumn(name="FUNC_ID"))11 private Collection funcionarios;12 }

    Cdigo Java 2.31: Departamento.java

    Figura 2.8: Personalizando a tabela de relacionamento

    Exerccios de Fixao

    www.k19.com.br 23

  • MAPEAMENTO 24

    10 Implemente duas entidades no pacote br.com.k19.modelo do projeto K19-Mapeamento: Fun-cionario e Departamento.

    1 @Entity2 public class Funcionario {3 @Id4 @GeneratedValue5 private Long id;67 private String nome;89 // GETTERS E SETTERS10 }

    Cdigo Java 2.32: Funcionario.java

    1 @Entity2 public class Departamento {3 @Id4 @GeneratedValue5 private Long id;67 private String nome;89 @OneToMany10 private Collection funcionarios = new ArrayList ();1112 // GETTERS E SETTERS13 }

    Cdigo Java 2.33: Departamento.java

    11 Adicione um departamento e um funcionrio no banco de dados. Crie uma classe chamadaAdicionaDepartamentoFuncionario no pacote br.com.k19.testes do projeto K19-Mapeamento.

    1 public class AdicionaDepartamentoFuncionario {2 public static void main(String [] args) {3 EntityManagerFactory factory =4 Persistence.createEntityManagerFactory("K21_mapeamento_pu");5 EntityManager manager = factory.createEntityManager ();67 manager.getTransaction ().begin();89 Funcionario f = new Funcionario ();10 f.setNome("Rafael Cosentino");1112 Departamento d = new Departamento ();13 d.setNome("Financeiro");14 d.getFuncionarios ().add(f);1516 manager.persist(f);17 manager.persist(d);1819 manager.getTransaction ().commit ();2021 manager.close();22 factory.close();23 }24 }

    Cdigo Java 2.34: AdicionaDepartamentoFuncionario.java

    12 Abra o MySQL Workbench e observe as propriedades das tabelas Departamento, Funcionario e

    24 www.k19.com.br

  • 25 MAPEAMENTO

    Departamento_Funcionario da base de dados K21_mapeamento_bd.

    Many to One

    Suponha que em nosso domnio existam as entidades Pedido e Cliente. As duas classes que mo-delariam essas entidades seriam definidas com as anotaes principais de mapeamento.

    1 @Entity2 class Pedido {3 @Id4 @GeneratedValue5 private Long id;6 }

    Cdigo Java 2.35: Pedido.java

    1 @Entity2 class Cliente {3 @Id4 @GeneratedValue5 private Long id;6 }

    Cdigo Java 2.36: Cliente.java

    Como existe um relacionamento entre pedidos e clientes, devemos expressar esse vnculo atravsde um atributo que pode ser inserido na classe Pedido. Supondo que um pedido pertena a um nicocliente, devemos utilizar um atributo simples para expressar esse relacionamento.

    1 @Entity2 class Pedido {3 @Id4 @GeneratedValue5 private Long id;67 private Cliente cliente;8 }

    Cdigo Java 2.37: Pedido.java

    Para informar a cardinalidade do relacionamento entre pedidos e clientes, devemos utilizar aanotao @ManyToOne no atributo.

    1 @Entity2 class Pedido {3 @Id4 @GeneratedValue5 private Long id;67 @ManyToOne8 private Cliente cliente;9 }

    Cdigo Java 2.38: Pedido.java

    No banco de dados, a tabela referente classe Pedido possuir uma join column vinculada tabela da classe Cliente. Por padro, o nome da join column formado pelo nome da entidade alvo

    www.k19.com.br 25

  • MAPEAMENTO 26

    do relacionamento, seguido pelo caractere _ e pelo nome do atributo que define a chave primriada entidade alvo.

    Figura 2.9: Tabelas correspondentes s classes Pedido e Cliente

    No exemplo de pedidos e clientes, o nome da join column seria cliente_id. Podemos alterar onome padro das join columns aplicando a anotao @JoinColumn.

    1 @Entity2 class Pedido {3 @Id4 @GeneratedValue5 private Long id;67 @ManyToOne8 @JoinColumn(name="cli_id")9 private Cliente cliente;10 }

    Cdigo Java 2.39: Pedido.java

    Figura 2.10: Personalizando a tabela Pedido

    Mais SobrePor padro, em um relacionamento Many to One, um objeto da primeira entidade noprecisa estar necessariamente relacionado a um objeto da segunda entidade. Para exi-

    gir que cada objeto da primeira entidade esteja relacionado a um objeto da segunda entidade,devemos usar o atributo optional da anotao ManyToOne.

    1 @Entity2 class Pedido {3 @Id4 @GeneratedValue5 private Long id;67 @ManyToOne(optional=false)8 private Cliente cliente;9 }

    Cdigo Java 2.40: Pedido.java

    Exerccios de Fixao

    26 www.k19.com.br

  • 27 MAPEAMENTO

    13 Implemente duas entidades no pacote br.com.k19.modelo do projeto K19-Mapeamento: Pe-dido e Cliente.

    1 @Entity2 public class Cliente {3 @Id4 @GeneratedValue5 private Long id;67 private String nome;89 // GETTERS E SETTERS10 }

    Cdigo Java 2.41: Cliente.java

    1 @Entity2 public class Pedido {3 @Id4 @GeneratedValue5 private Long id;67 @Temporal(TemporalType.DATE)8 private Calendar data;910 @ManyToOne11 private Cliente cliente;1213 // GETTERS E SETTERS14 }

    Cdigo Java 2.42: Pedido.java

    14 Adicione um cliente e um departamento no banco de dados. Crie uma classe chamada Adiciona-PedidoCliente no pacote br.com.k19.testes do projeto K19-Mapeamento.

    1 public class AdicionaPedidoCliente {2 public static void main(String [] args) {3 EntityManagerFactory factory = Persistence4 .createEntityManagerFactory("K21_mapeamento_pu");5 EntityManager manager = factory.createEntityManager ();67 manager.getTransaction ().begin();89 Cliente c = new Cliente ();10 c.setNome("Rafael Cosentino");1112 Pedido p = new Pedido ();13 p.setData(Calendar.getInstance ());14 p.setCliente(c);1516 manager.persist(c);17 manager.persist(p);1819 manager.getTransaction ().commit ();2021 manager.close();22 factory.close();23 }24 }

    Cdigo Java 2.43: AdicionaPedidoCliente.java

    www.k19.com.br 27

  • MAPEAMENTO 28

    15 Abra o MySQL Workbench e observe as propriedades das tabelas Cliente e Pedido da base dedados K21_mapeamento_bd.

    Many to Many

    Suponha que em nosso domnio existam as entidades Livro e Autor. As classes com as anotaesbsicas de mapeamento seriam mais ou menos assim:

    1 @Entity2 class Livro {3 @Id4 @GeneratedValue5 private Long id;6 }

    Cdigo Java 2.44: Livro.java

    1 @Entity2 class Autor {3 @Id4 @GeneratedValue5 private Long id;6 }

    Cdigo Java 2.45: Autor.java

    Como existe um relacionamento entre livros e autores, devemos expressar esse vnculo atravsde um atributo que pode ser inserido na classe Livro. Supondo que um livro possa ser escrito pormuitos autores, devemos utilizar uma coleo para expressar esse relacionamento.

    1 @Entity2 class Livro {3 @Id4 @GeneratedValue5 private Long id;67 private Collection autores;8 }

    Cdigo Java 2.46: Livro.java

    Para informar a cardinalidade do relacionamento entre livros e autores, devemos utilizar a ano-tao @ManyToMany na coleo.

    1 @Entity2 class Livro {3 @Id4 @GeneratedValue5 private Long id;67 @ManyToMany8 private Collection autores;9 }

    Cdigo Java 2.47: Livro.java

    No banco de dados, alm das duas tabelas correspondentes s classes Livro e Autor, uma jointable criada para relacionar os registros dos livros com os registros dos autores. Por padro, o nome

    28 www.k19.com.br

  • 29 MAPEAMENTO

    da join table a concatenao com _ dos nomes das duas entidades. No exemplo de livros e au-tores, o nome do join table seria Livro_Autor. Essa tabela possuir duas colunas vinculadas s en-tidades que formam o relacionamento. No exemplo, a join table Livro_Autor possuir uma colunachamada Livro_id e outra chamada autores_id.

    Figura 2.11: Tabelas correspondentes s classes Livro e Autor

    Para personalizar o nome join table e os nomes de suas colunas, podemos aplicar a anotao@JoinTable no atributo que define o relacionamento.

    1 @Entity2 class Livro {3 @Id4 @GeneratedValue5 private Long id;67 @ManyToMany8 @JoinTable(name="Liv_Aut",9 joinColumns=@JoinColumn(name="Liv_ID"),10 inverseJoinColumns=@JoinColumn(name="Aut_ID"))11 private Collection autores;12 }

    Cdigo Java 2.48: Livro.java

    Figura 2.12: Personalizando a tabela de relacionamento

    Exerccios de Fixao

    16 Implemente duas entidades no pacote br.com.k19.modelodo projeto K19-Mapeamento: Livro

    www.k19.com.br 29

  • MAPEAMENTO 30

    e Autor.

    1 @Entity2 public class Autor {3 @Id4 @GeneratedValue5 private Long id;67 private String nome;89 // GETTERS E SETTERS10 }

    Cdigo Java 2.49: Autor.java

    1 @Entity2 public class Livro {3 @Id4 @GeneratedValue5 private Long id;67 private String nome;89 @ManyToMany10 private Collection autores = new ArrayList ();1112 // GETTERS E SETTERS13 }

    Cdigo Java 2.50: Livro.java

    17 Adicione um livro e um autor no banco de dados. Crie uma classe chamada AdicionaLivro-Autor no pacote br.com.k19.testes do projeto K19-Mapeamento.

    1 public class AdicionaLivroAutor {2 public static void main(String [] args) {3 EntityManagerFactory factory =4 Persistence.createEntityManagerFactory("K21_mapeamento_pu");5 EntityManager manager = factory.createEntityManager ();67 manager.getTransaction ().begin();89 Autor a = new Autor();10 a.setNome("Rafael Cosentino");1112 Livro l = new Livro();13 l.setNome("JPA2");14 l.getAutores ().add(a);1516 manager.persist(a);17 manager.persist(l);1819 manager.getTransaction ().commit ();2021 manager.close();22 factory.close();23 }24 }

    Cdigo Java 2.51: AdicionaLivroAutor.java

    18 Abra o MySQL Workbench e observe as propriedades das tabelas Livro, Autor e Livro_Autorda base de dados K21_mapeamento_bd.

    30 www.k19.com.br

  • 31 MAPEAMENTO

    Relacionamentos Bidirecionais

    Quando expressamos um relacionamento colocando um atributo em uma das entidades, pode-mos acessar a outra entidade a partir da primeira. Por exemplo, considere o relacionamento entregovernadores e estados.

    1 @Entity2 class Estado {3 @Id4 @GeneratedValue5 private Long id;67 @OneToOne8 private Governador governador;910 // GETTERS E SETTERS11 }

    Cdigo Java 2.52: Estado.java

    Como o relacionamento est definido na classe Estado, podemos acessar o governador a partirde um estado.

    1 Estado e = manager.find(Estado.class , 1L);2 Governador g = e.getGovernador ();

    Cdigo Java 2.53: Acessando o governador a partir de um estado

    Tambm podemos expressar o relacionamento na classe Governador. Dessa forma, poderamosacessar um estado a partir de um governador.

    1 @Entity2 class Governador {3 @Id4 @GeneratedValue5 private Long id;67 @OneToOne8 private Estado estado;910 // GETTERS E SETTERS11 }

    Cdigo Java 2.54: Governador.java

    1 Governador g = manager.find(Governador.class , 1L);2 Estado e = g.getEstado ();

    Cdigo Java 2.55: Acessando um estado a partir de um governador

    A figura abaixo ilustra as tabelas Estado e Governador no banco de dados, assim como as joincolumns correspondentes aos relacionamentos.

    www.k19.com.br 31

  • MAPEAMENTO 32

    Figura 2.13: Tabelas Estado e Governador no banco de dados

    Note que foram criadas duas colunas de relacionamentos. A primeira na tabela Estado com onome governador_id e a segunda na tabela Governador com o nome estado_id. Nesse caso, oprovedor JPA est considerando dois relacionamentos unidirecionais distintos entre essas entidades.

    No entanto, de acordo com o modelo relacional, a relao entre estados e governadores deveriaser expressa com apenas uma coluna de relacionamento. Ou seja, o relacionamento entre gover-nadores e estados deveria ser bidirecional. Assim, devemos indicar em uma das classes que esserelacionamento bidirecional a juno de dois relacionamentos unidirecionais. Para isso, devemosadicionar o atributo mappedBy na anotao @OneToOne em uma das classes. O valor do mappedBydeve ser o nome do atributo que expressa o mesmo relacionamento na outra entidade.

    1 @Entity2 class Governador {3 @Id4 @GeneratedValue5 private Long id;67 @OneToOne(mappedBy="governador")8 private Estado estado;910 // GETTERS E SETTERS11 }

    Cdigo Java 2.56: Governador.java

    Figura 2.14: Tabelas Estado e Governador no banco de dados

    Exerccios de Fixao

    19 Considere um sistema de cobrana de ligaes telefnicas. Nesse sistema, temos uma entidadechamada Ligao e uma entidade chamada Fatura. Cada ligao est associada a uma nica fatura,enquanto que uma fatura est associada a mltiplas ligaes. Implemente classes para modelar essasduas entidades no pacote br.com.k19.modelo do projeto K19-Mapeamento.

    1 @Entity2 public class Ligacao {3 @Id @GeneratedValue4 private Long id;56 @ManyToOne7 private Fatura fatura;

    32 www.k19.com.br

  • 33 MAPEAMENTO

    89 private Integer duracao;1011 // GETTERS E SETTERS12 }

    Cdigo Java 2.57: Ligacao.java

    1 @Entity2 public class Fatura {3 @Id @GeneratedValue4 private Long id;56 @OneToMany7 private Collection ligacoes = new ArrayList ();89 @Temporal(TemporalType.DATE)10 private Calendar vencimento;1112 // GETTERS E SETTERS13 }

    Cdigo Java 2.58: Fatura.java

    20 Faa um teste para adicionar algumas ligaes e uma fatura. Adicione no pacote br.com.k19.tes-tes do projeto K19-Mapeamento uma classe chamada AdicionaFaturaLigacao.

    1 public class AdicionaFaturaLigacao {2 public static void main(String [] args) {3 EntityManagerFactory factory =4 Persistence.createEntityManagerFactory("K21_mapeamento_pu");5 EntityManager manager = factory.createEntityManager ();67 manager.getTransaction ().begin();89 Ligacao ligacao1 = new Ligacao ();10 ligacao1.setDuracao (162);1112 Ligacao ligacao2 = new Ligacao ();13 ligacao2.setDuracao (324);1415 Fatura fatura = new Fatura ();16 fatura.setVencimento(new GregorianCalendar (2012, 11, 20));1718 fatura.getLigacoes ().add(ligacao1);19 fatura.getLigacoes ().add(ligacao2);2021 ligacao1.setFatura(fatura);22 ligacao2.setFatura(fatura);2324 manager.persist(fatura);25 manager.persist(ligacao1);26 manager.persist(ligacao2);2728 manager.getTransaction ().commit ();2930 manager.close();31 factory.close();32 }33 }

    Cdigo Java 2.59: AdicionaFaturaLigacao.java

    21 Atravs do MySQL Workbench, verifique as tabelas criadas. Observe que a tabela Ligacao possuiuma coluna de relacionamento chamada fatura_id e a tabela Fatura_Ligacao vincula os registros

    www.k19.com.br 33

  • MAPEAMENTO 34

    das tabelas Ligacao e Fatura.

    22 Atravs do MySQL Workbench, apague primeiro a tabela Fatura_Ligacao e, em seguida, apagueas tabelas Fatura e Ligacao.

    23 Altere o cdigo da classe Faturade forma a criar um relacionamento bidirecional entre as faturase as ligaes.

    1 @Entity2 public class Fatura {3 @Id @GeneratedValue4 private Long id;56 @OneToMany(mappedBy="fatura")7 private Collection ligacoes = new ArrayList ();89 @Temporal(TemporalType.DATE)10 private Calendar vencimento;1112 // GETTERS E SETTERS13 }

    Cdigo Java 2.60: Fatura.java

    24 Execute a classe AdicionaFaturaLigacao para adicionar uma fatura e algumas ligaes. Atravsdo MySQL Workbench, verifique as tabelas criadas. Note que foram criadas apenas duas tabelas:Fatura e Ligacao.

    Objetos Embutidos

    Suponha que em nosso domnio exista uma entidade chamada Pessoa. Toda pessoa possui umendereo, que formado por pas, estado, cidade, logradouro, nmero, complemento e CEP. Paramelhorar a organizao da nossa aplicao, podemos criar duas classes: Pessoa e Endereco.

    1 @Entity2 class Pessoa {3 @Id4 @GeneratedValue5 private Long id;67 private String nome;89 @Temporal(TemporalType.DATE)10 private Calendar nascimento;1112 @OneToOne13 private Endereco endereco;14 }

    Cdigo Java 2.61: Pessoa.java

    1 @Entity2 class Endereco {3 @Id4 @GeneratedValue5 private Long id;67 private String pais;89 private String estado;

    34 www.k19.com.br

  • 35 MAPEAMENTO

    1011 private String cidade;1213 private String logradouro;1415 private int numero;1617 private String complemento;1819 private int cep;20 }

    Cdigo Java 2.62: Endereco.java

    Da forma como os mapeamentos esto definidos, duas tabelas sero criadas: uma para a classePessoa e outra para a classe Endereco. Na tabela Pessoa, haver uma coluna de relacionamento.

    Para recuperar os dados do endereo de uma pessoa, duas tabelas precisam ser consultadas atra-vs de uma operao de join. Esse tipo de operao no banco de dados custoso.

    Suponha que a tabela Endereco esteja relacionada apenas com a tabela Pessoa. Nesse caso, seriainteressante se pudssemos guardar os endereos das pessoas na prpria tabela Pessoa, tornandodesnecessria a existncia da tabela Endereco. No entanto, gostaramos de manter as classes Pessoae Endereco.

    Isso pode ser feito da seguinte forma. Na classe Pessoa, devemos remover a anotao de cardina-lidade @OneToOne. Na classe Endereco, devemos substituir a anotao @Entity por @Embeddable.Alm disso, no devemos definir uma chave para a classe Endereco, pois ela no define uma enti-dade.

    1 @Entity2 class Pessoa {3 @Id4 @GeneratedValue5 private Long id;67 private String nome;89 @Temporal(TemporalType.DATE)10 private Calendar nascimento;1112 private Endereco endereco;13 }

    Cdigo Java 2.63: Pessoa.java

    1 @Embeddable2 class Endereco {3 private String pais;45 private String estado;67 private String cidade;89 private String logradouro;1011 private int numero;1213 private String complemento;1415 private int cep;16 }

    www.k19.com.br 35

  • MAPEAMENTO 36

    Cdigo Java 2.64: Endereco.java

    Podemos conseguir o mesmo resultado da seguinte forma. Na classe Pessoa, devemos substituira anotao de cardinalidade @OneToOne por @Embedded. Na classe Endereco, devemos remover aanotao @Entity. Tambm, no devemos definir uma chave para a classe Endereco, pois ela nodefine uma entidade.

    1 @Entity2 class Pessoa {3 @Id4 @GeneratedValue5 private Long id;67 private String nome;89 @Temporal(TemporalType.DATE)10 private Calendar nascimento;1112 @Embedded13 private Endereco endereco;14 }

    Cdigo Java 2.65: Pessoa.java

    1 class Endereco {2 private String pais;34 private String estado;56 private String cidade;78 private String logradouro;910 private int numero;1112 private String complemento;1314 private int cep;15 }

    Cdigo Java 2.66: Endereco.java

    Exerccios de Fixao

    25 Crie uma classe para modelar endereos no pacote br.com.k19.modelo do projeto K19-Mapea-mento.

    1 public class Endereco {23 private String estado;45 private String cidade;67 private String logradouro;89 private int numero;1011 // GETTERS E SETTERS12 }

    36 www.k19.com.br

  • 37 MAPEAMENTO

    Cdigo Java 2.67: Endereco.java

    26 No pacote br.com.k19.modelodo projeto K19-Mapeamento, crie uma classe chamada Candidato.

    1 @Entity2 public class Candidato {3 @Id4 @GeneratedValue5 private Long id;67 private String nome;89 @Temporal(TemporalType.DATE)10 private Calendar nascimento;1112 @Embedded13 private Endereco endereco;1415 // GETTERS E SETTERS16 }

    Cdigo Java 2.68: Candidato.java

    27 Crie uma classe chamada AdicionaCandidatoEndereco no pacote br.com.k19.testes do pro-jeto K19-Mapeamento para adicionar alguns candidatos e endereos e depois execute-a.

    1 public class AdicionaCandidatoEndereco {2 public static void main(String [] args) {3 EntityManagerFactory factory =4 Persistence.createEntityManagerFactory("K21_mapeamento_pu");5 EntityManager manager = factory.createEntityManager ();67 manager.getTransaction ().begin();89 Endereco e = new Endereco ();10 e.setEstado("So Paulo");11 e.setCidade("So Paulo");12 e.setLogradouro("Av. Bigadeiro Faria Lima");13 e.setNumero (1571);1415 Candidato p = new Candidato ();16 p.setNome("Rafael Cosentino");17 p.setNascimento(new GregorianCalendar (1984, 10, 30));18 p.setEndereco(e);1920 manager.persist(p);2122 manager.getTransaction ().commit ();2324 manager.close();25 factory.close();26 }27 }

    Cdigo Java 2.69: AdicionaPessoaEndereco.java

    28 Execute a classe AdicionaCandidatoEndereco para adicionar um candidato e seu endereo.Atravs do MySQL Workbench, verifique a tabelas criada. Note que foi criada apenas a tabela Candidato.

    Herana

    www.k19.com.br 37

  • MAPEAMENTO 38

    O mapeamento objeto-relacional descreve como os conceitos de orientao a objetos so mape-ados para os conceitos do modelo relacional. De todos os conceitos de orientao a objetos, um dosmais complexos de se mapear o de Herana.

    A especificao JPA define trs estratgias para realizar o mapeamento de herana.

    Single Table

    Joined

    Table Per Class

    Single Table

    A estratgia Single Table a mais comum e a que possibilita melhor desempenho em relao avelocidade das consultas. Nessa estratgia, a super classe deve ser anotada com

    @Inheritance(strategy=InheritanceType.SINGLE_TABLE).

    O provedor JPA criar apenas uma tabela com o nome da super classe para armazenar os dadosdos objetos criados a partir da super classe ou das sub classes. Todos os atributos da super classee os das sub classes sero mapeados para colunas dessa tabela. Alm disso, uma coluna especialchamada DTYPE ser utilizada para identificar a classe do objeto correspondente ao registro.

    1 @Entity2 @Inheritance(strategy=InheritanceType.SINGLE_TABLE)3 public class Pessoa {4 @Id @GeneratedValue5 private Long id;67 private String nome;8 }

    Cdigo Java 2.70: Pessoa.java

    1 @Entity2 public class PessoaJuridica extends Pessoa{3 private String cnpj;4 }

    Cdigo Java 2.71: PessoaJuridica.java

    1 @Entity2 public class PessoaFisica extends Pessoa{3 private String cpf;4 }

    Cdigo Java 2.72: PessoaFisica.java

    38 www.k19.com.br

  • 39 MAPEAMENTO

    Figura 2.15: Tabela correspondente s classes Pessoa, PessoaJuridica e PessoaFisica

    A desvantagem da Single Table o consumo desnecessrio de espao, j que nem todos os cam-pos so utilizados para todos os registros. Por exemplo, se uma pessoa jurdica fosse cadastrada, ocampo cpf no seria utilizado. Da mesma forma, se uma pessoa fsica fosse cadastrada, o campocnpj no seria utilizado.

    Joined

    Nessa estratgia, uma tabela para cada classe da hierarquia criada. Em cada tabela, apenasos campos referentes aos atributos da classe correspondente so adicionados. Para relacionar osregistros das diversas tabelas e remontar os objetos quando uma consulta for realizada, as tabelas re-lacionadas s sub-classes possuem chaves estrangeiras vinculadas tabela associada super-classe.

    1 @Entity2 @Inheritance(strategy=InheritanceType.JOINED)3 public class Pessoa {4 @Id @GeneratedValue5 private Long id;67 private String nome;8 }

    Cdigo Java 2.73: Pessoa.java

    1 @Entity2 public class PessoaJuridica extends Pessoa {3 private String cnpj;4 }

    Cdigo Java 2.74: PessoaJuridica.java

    1 @Entity2 public class PessoaFisica extends Pessoa {3 private String cpf;4 }

    Cdigo Java 2.75: PessoaFisica.java

    www.k19.com.br 39

  • MAPEAMENTO 40

    Figura 2.16: Tabelas correspondentes s classes Pessoa, PessoaJuridica e PessoaFisica

    O consumo de espao utilizando a estratgia Joined menor do que o utilizado pela estratgiaSingle Table. Contudo, as consultas so mais lentas, pois necessrio realizar operaes de join pararecuperar os dados dos objetos.

    Table Per Class

    Nessa estratgia, uma tabela para cada classe concreta da hierarquia criada. Contudo, os dadosde um objeto no so colocados em tabelas diferentes. Dessa forma, para remontar um objeto no necessrio realizar operaes de join. A desvantagem desse modo que no existe um vnculoexplcito no banco de dados entres as tabelas correspondentes s classes da hierarquia.

    1 @Entity2 @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)3 public class Pessoa {4 @Id5 private Long id;67 private String nome;8 }

    Cdigo Java 2.76: Pessoa.java

    1 @Entity2 public class PessoaJuridica extends Pessoa {3 private String cnpj;4 }

    Cdigo Java 2.77: PessoaJuridica.java

    1 @Entity2 public class PessoaFisica extends Pessoa{3 private String cpf;4 }

    Cdigo Java 2.78: PessoaFisica.java

    40 www.k19.com.br

  • 41 MAPEAMENTO

    Figura 2.17: Tabelas correspondentes s classes Pessoa, PessoaJuridica e PessoaFisica

    Na estratgia Table Per Class, no podemos utilizar a gerao automtica de chave primriassimples e numricas.

    Exerccios de Fixao

    29 Adicione uma classe chamada Pessoa no pacote br.com.k19.modelo do projeto K19-Mapea-mento.

    1 @Entity2 @Inheritance(strategy=InheritanceType.SINGLE_TABLE)3 public class Pessoa {4 @Id @GeneratedValue5 private Long id;67 private String nome;89 // GETTERS E SETTERS10 }

    Cdigo Java 2.79: Pessoa.java

    30 Faa a classe PessoaJuridica no pacote br.com.k19.modelo do projeto K19-Mapeamento.

    1 @Entity2 public class PessoaJuridica extends Pessoa {3 private String cnpj;45 // GETTERS E SETTERS6 }

    Cdigo Java 2.80: PessoaJuridica.java

    31 Faa a classe PessoaFisica no pacote br.com.k19.modelo do projeto K19-Mapeamento.

    1 @Entity2 public class PessoaFisica extends Pessoa {3 private String cpf;45 // GETTERS E SETTERS6 }

    Cdigo Java 2.81: PessoaFisica.java

    32 Faa um teste para adicionar pessoas. Crie uma classe chamada AdicionaPessoa no pacotebr.com.k19.testes do projeto K19-Mapeamento.

    1 public class AdicionaPessoa {2 public static void main(String [] args) {

    www.k19.com.br 41

  • MAPEAMENTO 42

    3 EntityManagerFactory factory =4 Persistence.createEntityManagerFactory("K21_mapeamento_pu");5 EntityManager manager = factory.createEntityManager ();67 manager.getTransaction ().begin();89 Pessoa p1 = new Pessoa ();10 p1.setNome("Marcelo");1112 PessoaFisica p2 = new PessoaFisica ();13 p2.setNome("Rafael");14 p2.setCpf("1234");1516 PessoaJuridica p3 = new PessoaJuridica ();17 p3.setNome("K19");18 p3.setCnpj("567788");1920 manager.persist(p1);21 manager.persist(p2);22 manager.persist(p3);2324 manager.getTransaction ().commit ();2526 manager.close();27 factory.close();28 }29 }

    Cdigo Java 2.82: AdicionaPessoa.java

    33 Execute a classe AdicionaPessoa para adicionar algumas pessoas. Atravs do MySQL Work-bench, verifique a tabela criada. Note que foi criada apenas a tabela Pessoa.

    42 www.k19.com.br

  • ENTITY MANAGER

    CA

    P

    TU

    LO

    3Segundo a especificao JPA, as instncias das entidades so administradas pelos Entity Mana-

    gers. As duas principais responsabilidades dos Entity Managers so gerenciar o estado dos objetos esincronizar os dados da aplicao e do banco de dados.

    Estados

    necessrio conhecer o ciclo de vida das entidades para saber como os objetos so administra-dos pelos Entity Managers. Uma instncia de uma entidade pode passar pelos seguintes estados:

    Novo (New): Um objeto nesse estado no possui uma identidade (chave) e no est associado a umEntity Manager. O contedo desse objeto no enviado para o banco de dados. Toda instnciade uma entidade que acabou de ser criada com o comando new encontra-se no estado new doJPA.

    Administrado (Managed): Um objeto no estado managed possui uma identidade e est associadoa um Entity Manager. A cada sincronizao, os dados de um objeto no estado managed soatualizados no banco de dados.

    Desvinculado (Detached): Um objeto no estado detached possui uma identidade, mas no est as-sociado a um Entity Manager. Dessa forma, o contedo desse objeto no sincronizado como banco de dados.

    Removido (Removed): Um objeto no estado removed possui uma identidade e est associado a umEntity Manager. O contedo desse objeto ser removido do banco de dados quando houveruma sincronizao.

    Sincronizao com o Banco de Dados

    Uma sincronizao consiste em propagar para o banco de dados as modificaes, remoes einseres de entidades realizadas em memria atravs de um Entity Manager.

    Quando houver uma sincronizao, as modificaes realizadas no estado dos objetos managedso propagadas para o banco de dados, assim como os registros referentes aos objetos em estadoremoved so apagados do banco de dados. De acordo com a especificao, uma sincronizao spode ocorrer se uma transao estiver ativa.

    Cada Entity Manager possui uma nica transao associada. Para recuperar a transao asso-ciada a um Entity Manager, utilizamos o mtodo getTransaction(). Uma vez que a transao foirecuperada, podemos ativ-la atravs do mtodo begin().

    www.k19.com.br 43

  • ENTITY MANAGER 44

    Para confirmar uma transao, devemos usar o mtodo commit(). Quando esse mtodo invo-cado, ocorre uma sincronizao com o banco de dados e a transao finalizada.

    1 manager.getTransaction ().begin();2 . . .3 manager.getTransaction ().commit ();

    Cdigo Java 3.1: Iniciando e confirmando uma transao

    Com uma transao ativa, tambm podemos disparar uma sincronizao atravs do mtodoflush(). Apesar dos dados serem enviados para o banco de dados, eles no ficaro visveis paraoutras transaes. Esses dados sero considerados apenas nas consultas efetuadas dentro da pr-pria transao. Diversas chamadas ao mtodo flush() podem ser efetuadas dentro de uma mesmatransao.

    1 manager.getTransaction ().begin();2 . . .3 manager.flush();4 . . .5 manager.getTransaction ().commit ();

    Cdigo Java 3.2: Sincronizaes parciais atravs do mtodo flush()

    Toda modificao, remoo ou insero realizada no banco de dados devido s chamadas aomtodo flush() podem ser desfeitas atravs do mtodo rollback(). Uma chamada a esse mtodotambm finaliza a transao.

    1 manager.getTransaction ().begin();2 . . .3 manager.flush();4 . . .5 manager.getTransaction ().rollback ();

    Cdigo Java 3.3: Sincronizaes parciais atravs do mtodo flush()

    Flush Mode

    H duas polticas adotadas pelos provedores JPA em relao s sincronizaes: FlushModeTy-pe.AUTO (padro) e FlushModeType.COMMIT. No modo AUTO, o provedor JPA realiza sincronizaesautomticas antes de uma operao de consulta para garantir que as modificaes, remoes e in-seres ainda no sincronizadas sejam consideradas na consulta. J o comportamento no modoCOMMIT no est especificado. Consequentemente, cada provedor pode implementar o comporta-mento que achar mais adequado.

    Podemos configurar o flush mode no nvel de um Entity Manager afetando o comportamento emtodas as consultas realizadas atravs desse Entity Manager ou configurar apenas para uma consulta.

    1 manager.setFlushMode(FlushModeType.COMMIT);

    Cdigo Java 3.4: Configurando o flush mode de um Entity Manager

    1 query.setFlushMode(FlushModeType.COMMIT);2 query.setFlushMode(FlushModeType.AUTO);

    Cdigo Java 3.5: Configurando o flush mode de uma consulta

    44 www.k19.com.br

  • 45 ENTITY MANAGER

    Transies

    Uma instncia de uma entidade pode mudar de estado. Veremos a seguir as principais transies.

    NewManaged

    Um objeto no estado new passa para o estado managed quando utilizamos o mtodo persist()dos Entity Managers.

    1 @Entity2 class Pessoa {34 @Id @GeneratedValue5 private Long id;67 private String nome;89 // GETTERS E SETTERS10 }

    Cdigo Java 3.6: Pessoa.java

    1 manager.getTransaction ().begin();23 Pessoa p = new Pessoa ();4 p.setNome("Rafael Cosentino");5 manager.persist ();67 manager.getTransaction ().commit ();

    Cdigo Java 3.7: Persistindo uma instncia de uma entidade

    BDManaged

    Quando dados so recuperados do banco de dados, o provedor JPA cria objetos para armazenaressas informaes. Esses objetos estaro no estado managed.

    1 Pessoa p = manager.find(Pessoa.class , 1L);

    1 Pessoa p = manager.getReference(Pessoa.class , 1L);

    1 Query query = manager.createQuery("select p from Pessoa p");2 List lista = query.getResultList ();

    ManagedDetached

    Quando no queremos mais que um objeto no estado managed seja administrado, podemosdesvincul-lo do seu Entity Manager tornando-o detached. Dessa forma, o contedo desse objetono ser mais sincronizado com o banco de dados.

    www.k19.com.br 45

  • ENTITY MANAGER 46

    Para tornar apenas um objeto detached, devemos utilizar o mtodo detach():

    1 Pessoa p = manager.find(Pessoa.class , 1L);2 manager.detach(p);

    Para tornar detached todos os objetos administrados por um Entity Manager, devemos utilizar omtodo clear().

    1 manager.clear();

    Na chamada do mtodo close(), todos os objetos administrados por um Entity Manager tambmpassam para o estado detached.

    1 manager.close();

    DetachedManaged

    O estado de um objeto detached pode ser propagado para um objeto managed com a mesmaidentidade para que os dados sejam sincronizados com o banco de dados. Esse processo realizadopelo mtodo merge().

    1 Pessoa pessoaManaged = manager.merge(pessoaDetached);

    Managed Removed

    Quando um objeto managed se torna detached, os dados correspondentes a esse objeto no soapagados do banco de dados. Agora, quando utilizamos o mtodo remove(), marcamos um objetopara ser removido do banco de dados.

    1 Pessoa p = manager.find(Pessoa.class , 1L);2 manager.remove(p);

    O contedo do objeto ser removido no banco de dados quando o provedor realizar uma sincro-nizao.

    ManagedManaged

    O contedo de um objeto no estado managed pode ficar desatualizado em relao ao banco dedados se algum ou alguma aplicao alterar os dados na base de dados. Para atualizar um objetomanaged com os dados do banco de dados, devemos utilizar o mtodo refresh().

    1 Pessoa p = manager.find(Pessoa.class , 1L);2 manager.refresh(p);

    Exerccios de Fixao

    46 www.k19.com.br

  • 47 ENTITY MANAGER

    1 Crie um projeto no eclipse chamado K19-EntityManager. Copie a pasta lib do projeto K19-JPA2-Hibernate para o projeto K19-EnityManager. Depois adicione os jars dessa pasta no classpathdesse novo projeto.

    2 Abra o MySQL Workbench e apague a base de dados K21_entity_manager_bd se ela existir.Depois crie a base de dados K21_entity_manager_bd.

    3 Copie a pasta META-INF do projeto K19-JPA2-Hibernate para dentro da pasta src do projetoK19-EntityManager. Altere o arquivo persistence.xml do projeto K19-EntityManager, modifi-cando o nome da unidade de persistncia e a base da dados. Veja como o cdigo deve ficar:

    1 67 8 org.hibernate.ejb.HibernatePersistence 9 10 12 13 14 16 17 18 20 21 22

    Cdigo XML 3.1: persistence.xml

    4 Crie um pacote chamado br.com.k19.modelo no projeto K19-EntityManager e adicione a se-guinte classe:

    1 @Entity2 public class Pessoa {34 @Id @GeneratedValue5 private Long id;67 private String nome;89 // GETTERS E SETTERS10 }

    Cdigo Java 3.17: Pessoa.java

    5 Persista objetos atravs de um Entity Manager. Crie uma classe chamada TestePersist dentrode um pacote chamado br.com.k19.testes no projeto K19-EntityManager.

    1 public class TestePersist {2 public static void main(String [] args) {3 EntityManagerFactory factory =4 Persistence.createEntityManagerFactory("K21_entity_manager_pu");5 EntityManager manager = factory.createEntityManager ();

    www.k19.com.br 47

  • ENTITY MANAGER 48

    67 // ABRINDO A TRASACAO8 manager.getTransaction ().begin();910 // OBJETO NO ESTADO NEW11 Pessoa p = new Pessoa ();12 p.setNome("Rafael Cosentino");1314 // OBJETO NO ESTADO MANAGED15 manager.persist(p);1617 // SINCRONIZANDO E CONFIRMANDO A TRANSACAO18 manager.getTransaction ().commit ();1920 System.out.println("Pessoa id: " + p.getId());2122 manager.close();23 factory.close();24 }25 }

    Cdigo Java 3.18: TestePersist.java

    Execute e consulte o banco de dados atravs do MySQL Workbench!

    6 Busque objetos atravs de um Entity Manager dado a identidade dos objetos. Crie uma classechamada TesteFind dentro de um pacote br.com.k19.testes no projeto K19-EntityManager.

    1 public class TesteFind {2 public static void main(String [] args) {3 EntityManagerFactory factory =4 Persistence.createEntityManagerFactory("K21_entity_manager_pu");5 EntityManager manager = factory.createEntityManager ();67 // OBJETO NO ESTADO MANAGED8 Pessoa p = manager.find(Pessoa.class , 1L);9 System.out.println("Id: " + p.getId());10 System.out.println("Nome: " + p.getNome ());1112 manager.close();13 factory.close();14 }15 }

    Cdigo Java 3.19: TesteFind.java

    Execute e observe as mensagens no Console!

    7 Altere objetos no estado managed e depois faa um sincronizao com o banco de dados atra-vs de uma chamada ao mtodo commit(). Crie uma classe chamada TesteManaged dentro de umpacote br.com.k19.testes no projeto K19-EntityManager.

    1 public class TesteManaged {2 public static void main(String [] args) {3 EntityManagerFactory factory =4 Persistence.createEntityManagerFactory("K21_entity_manager_pu");5 EntityManager manager = factory.createEntityManager ();67 manager.getTransaction ().begin();89 // OBJETO NO ESTADO MANAGED10 Pessoa p = manager.find(Pessoa.class , 1L);1112 // ALTERANDO O CONTEUDO DO OBJETO13 p.setNome("Marcelo Martins");

    48 www.k19.com.br

  • 49 ENTITY MANAGER

    1415 // SINCRONIZANDO E CONFIRMANDO A TRANSACAO16 manager.getTransaction ().commit ();1718 manager.close();19 factory.close();20 }21 }

    Cdigo Java 3.20: TesteManaged.java

    Execute e consulte o banco de dados atravs do MySQL Workbench!

    8 Altere objetos no estado detached e depois faa um sincronizao com o banco de dados atravsde uma chamada ao mtodo commit(). Crie uma classe chamada TesteDetached dentro de umpacote br.com.k19.testes no projeto K19-EntityManager.

    1 public class TesteDetached {2 public static void main(String [] args) {3 EntityManagerFactory factory =4 Persistence.createEntityManagerFactory("K21_entity_manager_pu");5 EntityManager manager = factory.createEntityManager ();67 manager.getTransaction ().begin();89 // OBJETO NO ESTADO MANAGED10 Pessoa p = manager.find(Pessoa.class , 1L);1112 // OBJETO NO ESTADO DETACHED13 manager.detach(p);1415 // ALTERANDO O CONTEUDO DO OBJETO16 p.setNome("Jonas Hirata");1718 // SINCRONIZANDO E CONFIRMANDO A TRANSACAO19 manager.getTransaction ().commit ();2021 manager.close();22 factory.close();23 }24 }

    Cdigo Java 3.21: TesteDetached.java

    Execute e consulte o banco de dados atravs do MySQL Workbench!

    9 Busque um objeto no banco e ento desvincule-o atravs do mtodo detach(). Pa