SlideShare a Scribd company logo
1 of 93
Download to read offline
jpa
java	persistence	api
www.argonavis.com.br
introdução	a
Atualizado	em	22/01/2010:	tópicos	de	JPA	2.0
Conteúdo
• 1.	Relacionamento	entre	objetos	(revisão)	
• 2.	Mapeamento	objeto	relacional	
• 3.	Introdução	prática	
• 4.	Mapeamento	básico	de	entidades	
• 5.	Mapeamento	de	associações	
• 6.	Mapeamento	de	componentes	
• 7.	Mapeamento	de	entidades	em	herança	
• 8.	Queries	JPQL	
• 9.	Queries	Criteria	(JPA	2	/	Java	EE	6)	
• 10.	DAO	genérico
1. Relacionamento entre objetos
• Relacionamentos e objetos
• Tipos de relacionamento
• Cardinalidade
• Direção e visibilidade
• Exemplos
Relacionamentos
Produto
Item Pedido Cliente
FachadaLoja FachadaLojaMemoria
Serviços
Entidades
**
Objetos que são coisas: entidades
• Interface para dados: estado
• Classes geralmente possuem várias instâncias,
claramente identificadas
• Business Objects
• Produtos, Itens, Pedidos, Clientes
• Métodos operam sobre seus próprios dados e
sobre objetos dependentes
Objetos que fazem coisas: serviços
• Interface para operações: comportamento
• Classes geralmente representam uma única
instância (singleton)
• Dados (estado) compartilhados
• Application Services
• Fachadas, DAOs, Serviços, Camadas
• Métodos utilizam entidades e outros serviços
para realizar casos de uso
Tipos de relacionamento
• Ligação fraca: uso / associação
– Navio / Porto: porto existe sem navio e navio existe
sem porto e a destruição de um não afeta o outro
– Porto e Navio devem ter interfaces compatíveis (para
permitir que Navio possa atracar)
• Ligação forte: agregação
– Navio / Carga: cada container de carga acrescenta
(agrega) algo ao navio
– Cascade-delete: se navio afundar, a carga vai junto
• Ligação muito forte: composição
– Navio / Casco: o navio não pode ser utilizado
(inicializado) sem que seu casco esteja pronto antes
Em Java: associação
• Associação bidirecional (porto conhece seus navios e cada
navio sabe em que porto está)
class Porto {
private Set navios = new Set();
public Porto() {}
public void addNavio(Navio n) {
navios.add(n);
n.atracar(this);
}
public Set getNavios() {
return navios;
}
}
class Navio {
Porto porto;
public Navio() {}
public void atracar(Porto p) {
porto = p;
}
public boolean atracado() {
return porto != null;
}
}
Em Java: agregação
class Carga {
private double peso;
public Carga(double p) {
peso = p;
}
public double getPeso() {
return peso;
}
public double destruir() {
peso = 0.0;
}
}
class Navio {
private Set<Carga> containers;
private double peso = 100.0;
public Navio() {}
public void carregar(Carga c) {
containers.add(c);
}
public void afundar() {
for(Carga c: carga)
carga.destruir();
}
public double pesar() {
for(Carga c: carga) {
peso += carga.getPeso();
}
}
Agregação unidirecional (navio
conhece suas cargas, mas Carga
desconhece em que navio está)
Em Java: composição
class Estaleiro {
private Navio montar() {
Casco c = new CascoLongo();
Leme m = new LemeHidraulico();
return new Navio(c, m);
}
}
class Navio {
private Casco casco;
private Leme leme;
public Navio(Casco c, Leme m) {
casco = c;
leme = m;
}
public void virarDireita() {
leme.virarEsquerda();
}
public void virarEsquerda() {
leme.virarDireita();
}
}
class CascoLongo implements Casco {
int comprimento = 100;
int largura = 10;
}
abstract class Leme {
abstract void virarEsquerda();
abstract void virarDireita();
}
. . .
Cardinalidade
• Um para muitos, bidirecional
• Um para um, bidirecional
• Muitos para muitos, bidirecional
class Produto {
Item item;
}
class Item {
Produto produto;
}
class Pedido {
Set<Item> itens;
}
class Item {
Pedido pedido;
}
class Aluno {
Set<Turma> turmas;
}
class Turma {
Set<Aluno> alunos;
}
Os atributos
representam estados
visíveis (métodos get/
set)
Direção e visibilidade
• Um	para	muitos,	unidirecional	
• Muitos	para	um,	unidirecional	
• Um	para	um,	unidirecional
class Produto {
}
class Item {
Produto produto;
}
class Pedido {
Set<Item> itens;
}
class Item {
}
class Pedido {
}
class Item {
Pedido pedido;
}
equivalentes
2. Introdução ao mapeamento objeto
relacional (ORM)
• O que é ORM e como funciona?
• Dificuldades da ORM: incompatibilidades
• Usando uma camada de persistência JDBC
• Exemplo: tabelas e objetos + DAO
O que é ORM
• Object Relational Mapping
• Mapeamento de classes a esquemas de
bancos de dados relacionais
– Em tempo de configuração
• Utilização de uma API de persistência
– Em tempo de desenvolvimento
• Persistência transparente de objetos como
registros de um banco de dados
– Em tempo de execução
Por que usar ORM?
• Facilitar o desenvolvimento
– Simplificar, facilitar manutenção
– Separar responsabilidades
• Unir os benefícios de dois mundos
– Preservar as vantagens do paradigma relacional
(robustez, maturidade, facilidade de pesquisa, etc.)
para a camada de persistência
– Preservar as vantagens do paradigma orientado a
objetos (reuso, modularidade, herança,
polimorfismo, etc.) para a camada de negócios
Como funciona?
• Tempo de configuração
– Classes mapeadas a tabelas (esquemas)
• Tempo de execução
– Instâncias (objetos) automaticamente mapeadas a registros
conta correntista saldo
1 Gargantua 1370
2 Pantagruel 3450
3 Gargamel 800
4 Morticia 8200
Classe Conta
String codigo
String nome
double saldo
instância:Conta
codigo="4"
nome="Morticia"
saldo=8200
Tabela Conta
Banco	de	Dados	Relacional
Mas...
• Nem sempre o modelo relacional é equivalente
ao modelo de objetos
– O modelo normalizado mais eficiente geralmente tem
menos tabelas que os objetos do modelo de objetos
mais bem projetado
– Há objetos dependentes que são parte de um objeto
maior (colunas de uma tabela)
– Há objetos que são apenas visões de dados (dados de
várias tabelas)
• Uma boa ferramenta de ORM permite configurar
essas incompatibilidades
Mapeamento ideal
• Neste exemplo, o descasamento entre o
paradigma objeto e relacional não aparece
public class Cliente {
private String userid;
private String nome;
private String endereco;
private Set contas;
// (get/set), etc. ...
}
public class Conta {
private String numero;
private String nome;
private String tipo;
private Cliente usuario;
// métodos, get/set...
}
create table CLIENTE (
USERID VARCHAR(15) NOT NULL PRIMARY KEY,
NOME VARCHAR(50) NOT NULL,
ENDERECO VARCHAR(100)
)
create table CONTA (
NUMERO VARCHAR(10) NOT NULL PRIMARY Key,
NOME VARCHAR(50) NOT NULL,
TIPO VARCHAR(2) NOT NULL,
USUARIO VARCHAR(15) FOREIGN KEY REFERENCES CLIENTE
)
Foreign key USUARIO realiza o
relacionamento
Problema: granularidade
• Vários níveis são possíveis no modelo de objetos
– Baixa: Cliente com endereco (String)
– Mais alta: Endereco é objeto com propriedades: como cep,
cidade, rua, país, etc.
– Ainda mais alta: Rua é objeto com propriedades numero, etc.
• Há dois níveis apenas no modelo relacional
– Tabela (CLIENTE) e coluna (USERID, ENDERECO, etc.)
• Solução: múltiplos objetos mapeados a uma tabela
create table CLIENTE (
USERID VARCHAR(15) NOT NULL PRIMARY KEY,
NOME VARCHAR(50) NOT NULL,
ENDERECO_RUA VARCHAR(50),
ENDERECO_CIDADE VARCHAR(15),
ENDERECO_ESTADO VARCHAR(15),
ENDERECO_CEP VARCHAR(8),
ENDERECO_PAIS VARCHAR(15)
)
Cliente
Endereco
Problema: tipos e subtipos
• Modelo relacional não suporta herança nem
polimorfismo
– Queremos escrever queries que referem-se à classe
Conta e retornar instâncias concretas dessa classe!
• Requer implementação bem mais complexa
Associação
polimórfica!
Cliente Conta
ContaCredito ContaDebito
*
Problema: identidade
• No mundo relacional, existe um critério de igualdade:
– Chave-primária
• No mundo Java há dois
– Igualdade de referência (testado com ==)
– Equivalência (testado com equals())
• Além disso, mapeamento pode associar vários objetos a
uma mesma tabela!
• Complicações adicionais e problemas
– Chaves naturais
– Chaves compostas
– Ausência de chave
– Chaves que podem ser modificadas
problema de design:
deve ser corrigido
devem ser evitadas
em sistemas novos
Problema: associações
• Java representa associações como referências
(ou coleções de) referências para objetos
– São inerentemente direcionais
– Para implementar associações bidirecionais, é preciso
criar referências dos dois lados da associação
– Referências duplas podem ser associações M-N
• No mundo relacional, associações são
representadas por chaves estrangeiras
– Não são inerentemente direcionais
– Pode-se criar associações com projeção e joins
– Associações M-N requerem tabela extra
Problema: navegação em grafos
• Navegação em objetos
– Pula-se de um objeto para outro: obj.getA().getB()
sem que haja um caminho previamente definido
– O equivalente em SQL seria fazer um query para cada
pulo (nó do grafo)
– Portanto, a forma mais natural de navegar entre
objetos em OO é a forma menos eficiente de
recuperar dados em SQL
• Joins podem minimizar queries
– Mas perde-se a flexibilidade da definição dinâmica do
caminho de navegação
Solução
• Usar uma camada de persistência
para lidar com incompatibilidades
entre os paradigmas
– Usar uma arquitetura com separação
em camadas
– Cada camada concentra-se em um
interesse predominante
– Uma das camadas cuida da persistência
• Como implementar
– Escrever uma camada de persistência
(ex: DAO JDBC)
– Usar uma solução como ORM 

(ex: Hibernate)
Camada	de	Apresentação
Camada	de	Negócios
Camada	de	Persistência
3. Introdução prática: Hello World
• Passo-a-passo na construção de uma
aplicação JPA simples
– Criação de um projeto
– Criação dos objetos e das tabelas
– Definição dos mapeamentos
– Configuração do ambiente
– Implementação da persistência
• Siga os passos na sua máquina
Criação do projeto
• Crie um novo projeto no NetBeans
– Pacote raiz: jpaloja
• Dependências
– Inclua todos os JARs do diretório lib/ da distribuição
do Hibernate
– Inclua o driver JDBC do banco de dados
• Crie uma base de dados “aula” no MySQL
– Anote também o nome de usuário e senha para
acesso ao banco de dados
Próximos passos
• Criar tabela no banco
– Opcional: nós vamos gerar a tabela a partir do
próprio objeto Java anotado
• Criar o objeto (POJO)
• Criar as anotações de mapeamento entre o
POJO e a tabela (três anotações)
• Configuração
– Criar arquivo de configuração da persistência
(persistence.xml)
• Utilização
– Implementar classe de testes e usar a API
Regras para construção de POJOs
• Regras para construção de JavaBeans
– Construtor sem argumentos com visibilidade mínima de pacote
– Expor estado usando métodos get/set
• Exemplo: para propriedade do tipo String “texto” use
– String getTexto() e
– void setTexto(String texto)
• Métodos get/set devem seguir as convenções JavaBean
mas não precisam ser públicos
– O JPA enxerga os métodos private
• Métodos get/set a outras entidades determinam
associações e permitem navegação no grafo de objetos
Identidade
• O objeto que será mapeado via JPA deve
ter um campo que possa ser usado como
identificador
– Independente do objeto já ter algum atributo
unívoco (como userid)
• Deve ser um campo inteiro numérico (int,
Integer, long, Long)
– Será usado pelo JPA para controlar a
persistência
POJO: classe Produto
package jpaloja.pojos;
public class Produto {
private Long codigo;
private String nome;
private double preco;
public Produto() { } // construtor vazio (necessário)
public Produto(String nome, double preco) {
this.nome = nome;
this.preco = preco;
}
public Long getCodigo() {
return codigo;
}
private void setCodigo(Long codigo) {
this.codigo = codigo;
}
// outros métodos get/set (...)
}
Crie o POJO no pacote
jpaloja.pojos
O Netbeans guardará na pasta src
do projeto
O Netbeans gera
automaticamente o construtor
utilitário (com argumentos) e os
métodos get/set
Tabela
• Iremos mapear o Produto à seguinte tabela
• Não precisa criar a tabela neste momento pois
iremos gerá-la
CREATE TABLE produto
(
codigo int8 NOT NULL,
preco float8,
nome varchar(255),
CONSTRAINT produto_pkey PRIMARY KEY (codigo)
)
Mapeamento
• Acrescente as seguintes anotações de mapeamento no
arquivo Produto.java
package jpaloja.pojos;
import javax.persistence.*;
@Entity
public class Produto {
@Id
@GeneratedValue (strategy=GenerationType.AUTO)
private Long codigo;
...
}
Mapeamento: tabelas e classes
• O mapeamento da classe à tabela é realizada através da
anotação @Entity
– Se o nome da tabela não for informado, ela terá o mesmo nome
que a classe
package jpaloja.pojos;
import javax.persistence.*;
@Entity
@Table(name = “PRODUTO”)
public class Produto {
...
}
Mapeamento: identificador
• O identificador é mapeado através da anotação @Id à chave
primária da tabela
• A anotação @GeneratedValue informa como a chave será
incrementada pelo provedor de persistência
package jpaloja.pojos;
import javax.persistence.*;
@Entity
public class Produto {
@Id
@GeneratedValue (strategy=GenerationType.AUTO)
private Long codigo;
}
Mapeamento: propriedades
• As propriedades escalares são mapeadas através da anotação
@Column
– Se ela for omitida, todos os métodos automaticamente serão
considerados parte da interface de mapeamento
@Entity
@Table(name = “PRODUTO”)
public class Produto {
@Column(name = “CODIGO”)
private Long codigo;
@Column(name = “NOME”)
private String nome;
@Column(name=”PRECO”)
private double preco;
}
Configuração da persistência
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" ... >
<persistence-unit name="LojaVirtual">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!-- <jta-data-source>java:/LojaVirtualDS</jta-data-source> -->
<class>lojavirtual.Produto</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/test"/>
<property name="hibernate.transaction.manager_lookup_class" 

value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
<property name="hibernate.show_sql" value="true"/>
<!-- <property name="hibernate.hbm2ddl.auto" value="create"/> -->
</properties>
</persistence-unit>
</persistence>
Descomente na primeira
execução para gerar as
tabelas, depois comente
de novo.
Guarde em src/META-INF com
o nome persistence.xml
Utilização da persistência
• Para usar o mecanismo de persistência do JPA, é
preciso inicializar uma sessão do EntityManager
– O EntityManager oferece uma API de operações de
persistência (gravação, leitura, transações)
– Cada sessão ocupa um thread e é obtida a partir de
um EntityManagerFactory ou via injeção de
dependências (em EJB 3)
• No nosso exemplo usaremos EJB 3
– Será preciso criar um EJB (Session Bean) para
gerenciar a persistência, e disponibilizá-lo no JBoss
Principais interfaces
• Todas do pacote javax.persistence
• Persistence
– Oferece um factory method para criar EMF
• EntityManagerFactory
– Equivalente a SessionFactory do Hibernate
• EntityManager
– Equivalente a Session do Hibernate
• Query
– Equivalente a Query do Hibernate
• EntityTransaction
– Equivalente a Transaction do Hibernate
Alguns métodos de EntityManager
• void	persist(E	objeto)	
– Insere	objeto	na	camada	de	persistência	
• E	find(E.class,	Object	id)	
– Localiza	objeto	pelo	ID	
• E	merge(E	objeto)	
– Atualiza	objeto	(e	cascade,	se	houver)	
• Query	createQuery(String	jpql)	
– Cria	um	query	
• Outros:		
– remove(E	objeto),	flush(),	close(),	getTransaction()
Inserir
package loja;
import jpaloja.pojos.Produto;
import javax.persistence.*;
public class Inserir {
public static void main(String[] args) {
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("LojaVirtual");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Produto p1 = new Produto("Giroscopio", 123.89);
Produto p2 = new Produto("Tesoura", 23.14);
em.persist(p1);
em.persist(p2);
tx.commit();
em.close();
}
}
Listar
package loja;
public class Listar {
public static void main(String[] args) {
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("LojaVirtual");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
Query q = em.createQuery("select p from Produto p”);
List produtos = q.getResultList();
System.out.println( produtos.size() + “ produtos encontrados!”);
for (Object o: produtos.getResultList()) {
Produto p = (Produto) o;
System.out.println( p.getNome() + “ $” + p.getPreco() );
}
tx.commit();
em.close();
}
}
SessionContext do EJB
• Para obter, use injeção de recursos
@Resource

SessionContext ctx;
• A partir do contexto, pode-se localizar objetos e recursos via
JNDI
DataSource ds = ctx.lookup("java:/DefaultDS");
EntityManagerFactory emf = ctx.lookup("emf/loja");
Queue fila = ctx.lookup("jms/Queue");
• É melhor obter um EntityManager usando injeção de recursos
com @PersistenceContext
@PersistenceContext
private EntityManager em;
EJB usando persistência
@Stateless
public class ProdutoFacadeBean implements ProdutoFacadeBeanRemote {
@PersistenceContext(unitName="LojaVirtual")
private EntityManager em;
public List<Produto> retrieveAll() {
Query query = em.createQuery("select p from Produto p");
List<Produto> produtos = query.getResultList();
return produtos;
}
public Produto insert(Produto p) {
em.persist(p);
return em.merge(p);
}
...
Execução
• Isto é um cliente EJB remoto
– Sua execução requer a configuração de um cliente Java EE (contendo JARs /
client do JBoss + jndi.properties informando a localização do servidor)
public class ProdutoTest {
public static void main(String[] args) throws NamingException {
ProdutoFacadeBeanRemote facade;
Context jndi = new InitialContext();
Object obj = jndi.lookup("ProdutoFacadeBean/remote");
facade = (ProdutoFacadeBeanRemote) obj;
Produto p1 = new Produto();
p1.setNome("Produto 1");
p1.setPreco(30.00);
Produto p2 = new Produto();
p2.setNome("Produto 2");
p2.setPreco(50.00);
facade.insert(p1);
facade.insert(p2);
...
JP-QL
• JP Query Language é um dialeto orientado a
objetos do SQL
– Não é uma linguagem de manipulação de dados
(como SQL)
– Não serve para inserir, remover, atualizar (tem como
fazer, mas não se recomenda)
– É usada apenas para recuperação de objetos
• Exemplo
Query q = 

session.createQuery("select u from User u where u.firstname = :fname");
q.setString("fname", "Max");
List result = q.getResultList();
4. Mapeamento de entidades
• A classe deve ser descrita como entidade
– anotada com @Entity (ou declarada como <entity> no
deployment descriptor orm.xml)
– ter um campo @Id (a menos que participe como subclasse de
uma hierarquia mapeada em JPA)
• Deve ter construtor sem argumentos
• Não pode
– ser interface ou um enum ou classe final
– ter variáveis de instância ou métodos finais
• Deve implementar java.io.Serializable se precisar ser
passada por valor
– Ex: se objeto for usado por um cliente remoto, como em EJBs
que têm interface @Remote
Entidades
• Suportam herança, associações polimórficas,
queries polimórficos
– Podem estender classes comuns e vice-versa
– Somente entidades podem ser usadas em queries JPA
• Seu estado persistente é representado pelas
suas variáveis de instância
– acessado via propriedades (métodos get/set) ou
através de suas variáveis de instância
– variáveis de instância não declaradas transient e que
não tenham a anotação @Transient são consideradas
persistentes.
Entidades
• Assinaturas válidas para propriedades:
– Propriedades escalares (value-types) ou lado unitário de
associações com entidades (@Column):

T getProperty() e void setProperty(T t)
– Coleções de escalares (value-types) ou lado múltiplo de
associações com entidades (@JoinColumn)

Set<T> getProperty() e void setProperty(Set<T>) 

(ou Collection, List ou Map)
• Tipos permitidos:
– Value-types: primitivos, String, BigInteger, BigDecimal, Date,
Calendar, Time, Timestamp, byte[], Byte[], char, Character[],
enums e coleções desses valores
– Tipos serializáveis e coleções de tipos serializáveis
– Entidades e coleções de entidades
Exemplo de mapeamento
@Entity
public class Cliente implements Serializable {
@Id
private Long id;
private String nome;
private Endereco endereco;
@OneToMany
private Set<Pedido> pedidos = new HashSet();
@ManyToMany
private Set<Pagamento> formasPagamento = new HashSet();
public Cliente() {}
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
...
public Collection<Order> getPedidos() { return pedidos; }
public void setPedidos(Collection<Pedido> pedidos) { this.pedidos = pedidos; }
public Set<Pagamento> getFormasPagamento() { return formasPagamento; }
...
}
Usando o mínimo de anotações!
Anotações ausentes (ex:
@Column, @Table, etc.) resultam
em comportamento default (ex:
tabela com mesmo nome que
classe)
As anotações também possuem
muitas propriedades que podem
ser configuradas; se omitidas, são
usadas as propriedades default
Ciclo de vida de uma entidade: 

breve resumo
• A operação new cria uma instância no estado transiente
– Entidade transiente = new Entidade()
• Para tornar a instância persistente é preciso utilizar a
API do EntityManager
– entityManager.persist(transiente);
– Entidade persistente = entityManager.merge(transiente);
• Toda entidade tem uma chave primária.
– Indicada pela anotação @Id (pode ser na superclasse) e
geralmente definida pelo serviço de persistência
– Aplicação nunca deve mudar valor de chave primária.
• Fora do escopo do EntityManager, objeto que já foi
persistente é considerado desconectado (detached)
– Pode ser re-ligado com um merge:

Entidade persistente = entityManager.merge(detached);
5. Mapeamento de associações
• Associações no JPA funcionam da mesma maneira que
associações de objetos em Java
– Associações de objetos em JPA são naturalmente unidirecionais
e não são gerenciadas pelo container (como em EJB 2.1)
• Associações são sempre relacionamentos entre
entidades (diretamente ou via coleções)
• Três tipos
– @OneToOne
– @ManyToOne
– @ManyToMany
• Duas possibilidades para cada tipo
– Unidirecional
– Bidirecional
Associações
• @ManyToOne é a associação mais comum
– O modelo relacional é naturalmente um-para-muitos
– Uma referência simples de objeto é um-para-muitos
– Em associações bidirecionais, do outro lado deve haver @OneToMany
• @OneToOne requer constraints (que são gerados) nas tabelas para
garantir consistência da associação
• @ManyToMany mapeia três tabelas a dois objetos
• Em associações bidirecionais, há anotações de ambos os lados
– Atributo mappedBy é usado em associações bidirecionais para
informar o nome do atributo da outra classe que faz a associação
– @OneToOne CPF cpf; 

à @OneToOne(mappedBy="cpf") Cliente cliente;
– @ManyToMany(mappedBy="alunos") Set<Turma> turmas; 

à @ManyToMany(mappedBy="turmas") Set<Aluno> alunos;
– @ManyToOne(mappedBy="item") Set<Produto> produtos; 

à @OneToMany Item item;
@ManyToOne
• Pode-se mapear tudo com @ManyToOne
• Associações @OneToOne são raras
– Muitas vezes representam composições que devem ser
preferivelmente implementadas usando @Embedded /
@Embeddable (veremos na parte 3, adiante)
• Associações @ManyToMany podem ser implementadas
com três objetos e duas associações @ManyToOne
– As vezes isto é mais simples e adequado, quando se precisa de
um objeto mapeando a associação (join-table)
• Várias anotações e atributos permitem configurar
ajustes finos dos mapeamentos
• Escolha a solução mais simples e adequada ao seu
projeto
ManyToOne unidirecional
@Entity	
public	class	Produto	{	
				@Id	@GeneratedValue	
				int	codigo;	
				String	nome;	
				double	preco;	
				public	int	getCodigo()	{	
								return	codigo;	
				}	
				public	void	setCodigo(int	codigo)	{	
								this.codigo	=	codigo;	
				}	
				public	String	getNome()	{	
								return	nome;	
				}	
				public	void	setNome(String	nome)	{	
								this.nome	=	nome;	
				}	
...
@Entity
public class Item {
@ManyToOne
private Produto produto;
public Produto getProduto() {
return produto;
}
public void setProduto(Produto produto) {
this.produto = produto;
}
public double subtotal() {
return this.produto.getPreco() * this.quantidade;
}
...
Classe Produto não
sabe da existência da
associação*
Método de negócio que utiliza-se da
associação para realizar uma operação
* Esses dados são insuficientes para a geração automática do esquema (as tabelas devem existir antes)
ManyToOne bidirecional
@Entity	
public	class	Pedido	{	
				@OneToMany(mappedBy="pedido")	
				private	Set<Item>	itens	=		new	HashSet<Item>();	
				public	Set<Item>	getItens()	{	
								return	itens;	
				}	
				public	void	setItens(Set<Item>	itens)	{	
								this.itens	=	itens;	
				}	
				public	void	addItem(Item	item)	{	
								itens.add(item);	
								item.setPedido(this);	
				}	
				public	double	subtotal()	{	
								double	subtotal	=	0;	
								for	(Item	item	:	itens)	{	
												subtotal	+=	item.subtotal();	
								}	
								return	subtotal;	
				}	
...
@Entity	
public	class	Item	{	
				@ManyToOne	
				private	Pedido		pedido;	
				public	Pedido	getPedido()	{	
								return	pedido;	
				}	
				public	void	setPedido(Pedido	pedido)	{	
								this.pedido	=	pedido;	
				}		
					
				public	double	subtotal()	{	...	}	
...
Utilitário para facilitar a adiçção de
itens na associação (atualiza os dois
lados da associação)
Método de negócio que utiliza-se da
associação para realizar uma operação
@ManyToMany
• Default: @ManyToMany nos Set de cada lado da
associação, informando o campo de mapeamento
(mappedBy)
– Em associações bidirecionais, é preciso atualizar os dois lados
– Usando-se Set e mappedBy, garante-se a não duplicação de
dados quando objeto é adicionado duas vezes na coleção
• Muitos ajustes possíveis
– Uso de List ou Collection (com ou sem @CollectionID) ou Map
(com @MapKey)
– Configuração de @JoinTable, @JoinColumn, @SecondaryTable
• Essas configurações avançadas não serão abordadas
neste curso
ManyToMany bidirecional
@Entity	
public	class	Aluno	{	
				@Id	@GeneratedValue	
				private	int	id;	
				@ManyToMany(mappedBy="alunos")	
				private	Set<Turma>	turmas;	
				public	Set<Turma>	getTurmas()	{	
								return	turmas;	
				}	
				public	void	setTurmas(Set<Turma>	turmas)	{	
								this.turmas	=	turmas;	
				}	
				public	void	matricular(Turma	turma)	{	
								turmas.add(turma);	
								turma.addAluno(this);	
				}	
...	
}
@Entity	
public	class	Turma	{	
				@Id	@GeneratedValue	
				private	int	id;	
				@ManyToMany(mappedBy="turmas")	
				private	Set<Aluno>	alunos;	
				public	Set<Aluno>	getAlunos()	{	
								return	alunos;	
				}	
				public	void	setAlunos(Set<Turma>	turmas)	{	
								this.alunos	=	alunos;	
				}	
				public	void	addAluno(Aluno	aluno)	{	
								alunos.add(aluno);	
								aluno.matricular(this);	
				}	
...	
}
Métodos utilitários para adicionar alunos e turmas
(não há duplicação porque é um Set)
@OneToOne
• Muitas vezes é desnecessário -relacionamento pode ser
representado de outras formas
– Pode ser @ManyToOne unidirecional
– Pode ser implementado com o componente na mesma tabela
(@Embedded)
• Duas formas de mapeamento @OneToOne
– Associação de chave estrangeira (default)
– Associação de chave primária (não pode definir um
@JoinColumn, mas é anotado com @PrimaryKeyJoinColumn
• Neste curso utilizaremos apenas o mapeamento default
OneToOne bidirecional
@Entity	
public	class	Cliente	{	
				@OneToOne(mappedBy="cliente")	
				private	CPF	cpf;	
				public	CPF	getCPF()	{	
								return	cpf;	
				}	
				public	void	setCPF(CPF	cpf)	{	
								this.cpf	=	cpf;	
				}		
...
@Entity	
public	class	CPF	{	
				@OneToOne	
				private	Cliente	cliente;	
				public	Cliente	getCliente()	{	
								return	cliente;	
				}	
				public	void	setCliente(Cliente	cliente)	{	
								this.cliente	=	cliente;	
				}		
...
Só é necessário informar o
mappedBy em um dos lados
da associação
Cascades: persistência transitiva
• Para acrescentar um item em um pedido, é preciso atualizar dois
objetos
Pedido p = new Pedido();
Item i = new Item();
p.addItem(i); // atualiza dois objetos
• Para persistir essa alteração, também é preciso sincronizar os dois
objetos
em.persist(p);
em.persist(i);
• O ideal é fazer isto automaticamente: cascade
@OneToMany(cascade={CascadeType.PERSIST},	

											mappedBy="item"	)

private	Set<Item>	itens	=	new	HashSet<Item>();
– Quando um Pedido for persistido no banco, quaisquer itens que
estiverem na sua hierarquia de objetos também serão persistidos
CascadeType
• O atributo cascade recebe um array {} de opções
• Há várias opções para CascadeType. Algumas das mais
importantes são
– PERSIST
– MERGE
– REMOVE
• Normalmente, usa-se PERSIST com MERGE (inserts e
updates feitos automaticamente)
@OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE})
• Pode-se usar CascadeType.ALL para que todas as
operações sejam transitivas
Recuperação de dados: lazy
• Se você usar um cliente externo que não mantém aberta
a sessão do EntityManager, poderá ter exceções de
inicialização lazy (inicialização preguiçosa) quando for
acessar objetos dentro de coleções
– O query, por default, só retorna a coleção com os ponteiros
para os objetos, e eles só podem ser recuperados do banco se
houver uma sessão aberta
– Como lidar com isto será tratado mais adiante
• Uma forma rápida de resolver o problema (por
enquanto) é declarar nas associações o atributo
fetch=FetchType da forma
@OneToMany(mappedBy="pedido",	fetch=FetchType.EAGER)	
private	Set<Item>	itens	=	new	HashSet<Item>();
Outras anotações de associações
• @JoinColumn(name="coluna", ...)
– Propriedades que não são associações informam a
coluna da tabela a qual estão mapeadas com
@Column
– Associações informam a coluna da associação (foreign
key) usando @JoinColumn
– Se não informada, o sistema assume que a coluna
tem o mesmo nome que o atributo
• Consulte a especificação para maiores detalhes
sobre as outras anotações e seus atributos
6. Mapeamento de composição
• Em ORM, objetos que formam uma composição
compartilham a mesma tabela
– Em JPA, classes que são componentes são mapeadas como
@Embeddable (e não como @Entity) e suas propriedades
anotadas como @Embedded na entidade que as contém
Cliente	
nome	
email	
cartao
Endereco
Rua
CEP
Cidade
enderecoEntrega	
enderecoCobranca
nome email cartao ent_rua ent_cep ent_cidade cob_rua cob_cep cob_cidade
											:Ciente		 			enderecoEntrega:Endereco			 enderecoCobranca:Endereco
<<Entidade>> <<Componente>>
@Entity @Embeddable
@Embedded
Composições (@Embedded)
• O objeto embutido (componente) na entidade é a parte
dependente da relação de composição
– Uma composição ocorre quando uma entidade, que tem
identidade na tabela, está composta por objetos que não têm
identidade na tabela (seus dados são parte da tabela)
– A remoção do registro no banco remove a entidade e seus
objetos componentes (não confunda com cascade-delete)
• O objeto embutido é propriedade da entidade
– Só existem como objetos, mas não como tabelas
• Muitas associações 1-1 podem ser implementados como
objetos embutidos
– Ex: a associação Cliente-CPF mostrada anteriormente
Exemplo com @Embedded
@Entity
@Table(name="CLIENTE")
public class Cliente {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long codigo;
private String nome;
...
@Embedded
private Endereco enderecoCobranca;
@Embedded
@AttributeOverrides({
@AttributeOverride(name="rua", column=@Column(name="ENT_RUA")),
@AttributeOverride(name="cep", column=@Column(name="ENT_CEP")),
@AttributeOverride(name="cidade", column=@Column(name="ENT_CIDADE")),
})
private Endereco enderecoEntrega;
...
@Embeddable
public class Endereco {
@Column(name="COB_RUA")
private String rua;
@Column(name="COB_CEP")
private String cep;
@Column(name="COB_CIDADE")
private String cidade;
...
}
reusa mesma classe Endereco, mas
redefine mapeamentos
• Herança é o descasamento mais visível entre os mundos
relacional e orientado a objetos
– Mundo OO possui relacionamento “é um” e “tem um”
– Mundo relacional apenas possui relacionamento “tem um”
• Há várias estratégias [Ambler 2002]*
– Uma tabela por classe concreta: modelo relacional ignora
herança e polimorfismo (polimorfismo implícito)
– Uma tabela por hierarquia de classes: permite polimorfismo
com tabelas não normalizadas mais uma coluna extra contendo
informação de tipo
– Uma tabela por subclasse: representa relacionamentos “é um”
através de relacionamentos “tem um” (chave estrangeira)
7. Mapeamento de herança
a. Tabela por classe concreta
• Mapeia classes concretas a tabelas
@Entity	
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)		
public	abstract	class	Pagamento	{	
					@Id	@GeneratedValue	private	long	id;	
}
Pagamento	
id	
valor
Credito	
numero	
validade
ID VALOR NUMERO VALIDADE
5
<<Entidade>>
@Entity
Debito	
banco	
conta
<<Entidade>>
@Entity
ID VALOR BANCO CONTA
5
CREDITO
DEBITO
@Entity	
public	class	Debito	extends	Pagamento	{...}
@Id declarado apenas na
superclasse
Tabela por classe concreta
• Vantagens
– Mapeamento direto entre classe e tabela normalizada
• Desvantagens
– Queries mais complexos e ineficientes
• O query polimórfico
select p from Pagamento p where p.valor > 1000
gera um SQL (conceitual) com subquery que concatena
queries nas tabelas com union:
– select ID, VALOR, NUMERO, VALIDADE, BANCO, CONTA from (

select ID, VALOR, NUMERO, VALIDADE, 

null as BANCO, null as CONTA from CREDITO 

union
select ID, VALOR, null as NUMERO, null as VALIDADE, 

BANCO, CONTA from DEBITO 

) where VALOR > 1000
b. Tabela por hierarquia de classes
@Entity	
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)	
@DiscriminatorColumn(name="TIPO")	
public	abstract	class	Pagamento	{	
					@Id	@GeneratedValue	private	long	id;	
}
Pagamento	
id	
valor
Credito	
numero	
validade
ID TIPO VALOR NUMERO VALIDADE BANCO CONTA
5 crd 100.0 23459403 12/15 null null
6 deb 100.0 null null 1234-5 993423-3
<<Entidade>>
@Entity
Debito	
banco	
conta
<<Entidade>>
@Entity
PAGAMENTO
@Entity	
@DiscriminatorValue("deb")	
public	class	Debito	extends	Pagamento	{...}
Coluna (DiscriminatorColumn)
presente na tabela mas sem
mapeamento na classe
b. Tabela por hierarquia de classes
• Mapeia-se a hierarquia inteira a uma única tabela
– Tabela inclui coluna (não mapeada) para identificar a classe
– Há colunas para todas as propriedades de todas as classes
• Vantagens
– Forma mais eficiente de implementar polimorfismo.
– Query polimórfico:
select ID, VALOR, BANCO, CONTA, NUMERO, VALIDADE from
PAGAMENTO where VALOR > 1000
– Query em classe concreta:
select ID, VALOR, BANCO, CONTA, NUMERO, VALIDADE from
PAGAMENTO where TIPO = 'deb' and VALOR > 1000
• Desvantagens
– Tabelas não normalizadas
– Colunas de propriedades declaradas em subclasses precisam
aceitar valores nulos (pode ser ruim para grandes hierarquias)
c. Tabela por subclasse
• Mapeia classes a tabelas
@Entity	
@Inheritance(strategy=InheritanceType.JOINED)		
public	abstract	class	Pagamento	{	
					@Id	@GeneratedValue	private	long	id;	
}
Pagamento	
id	
valor
Credito	
id	
numero	
validade
ID NUMERO VALIDADE
9
<<Entidade>>
@Entity
Debito	
id	
banco	
conta
<<Entidade>>
@Entity
ID BANCO CONTA
5
CREDITO
DEBITO
@Entity	
public	class	Debito	extends	Pagamento	{...}
ID VALOR
5
PAGAMENTO
ID é PK e FK
Uma tabela por subclasse
• Herança como relacionamentos de chave estrangeira
– Cada subclasse tem sua própria tabela
– Cada tabela possui colunas apenas para campos não-herdados, e
chave primária que é chave estrangeira da superclasse
– Recuperação de dados através de um join das tabelas
• Vantagens
– Modelo relacional normalizado
– Evolução e restrições de integridade simples
– Classes/tabelas criadas sem afetar classes/tabelas existentes
• Desvantagens
– Performance baixa em hierarquias complexas
– Difícil de codificar a mão (ruim para integrar com JDBC legado)
• Queries
– Outer join para pesquisas polimórficas, inner join para queries
em classes concretas
Qual estratégia usar?
• Se não houver necessidade de queries polimórficos ou
associações
– Tabela por Classe Concreta (TABLE_PER_CLASS)
• Se houver necessidade de associações polimórficas, e
hierarquia for simples
– Tabela por Hierarquia (SINGLE_TABLE)
• Se houver necessidade de associações polimórficas
mas hierarquia grande (ou não puder usar tabelas não
normalizadas)
– Tabela por Subclasse (JOINED)
8. Queries JPQL
• Toda pesquisa no banco é feita através de Java
Persistence Query Language (JPQL)
– Linguagem de recuperação de dados similar a outras
linguagens de query de objetos (HQL, EJB-QL, etc.)
– Parece com SQL, mas é diferente: opera sobre objetos e não
tabelas – é mais simples
• Queries são objetos da classe Query
– Podem ser criados através métodos de EntityManager
– Instruções do query podem ser passadas diretamente na
criação do query ou declarados em anotações @NamedQuery
– Queries podem ser parametrizados
• Após sua execução, os dados podem ser recuperados
através de métodos da classe Query.
API essencial para Queries JPQL
• EntityManager
– Query createQuery("query jpql");
– Query createNamedQuery("nome de query");
• Query
– List<Tipo> getResultList();
– Object getSingleResult();
– Query setParameter(String var, Object obj);

Query setParameter(int pos, Object obj);
– int executeUpdate();
Named Queries
@Entity	
@NamedQueries({	
				@NamedQuery(name="produtoMaisBarato",	
								query="SELECT	x	FROM	Produto	x	WHERE	x.preco	>	?1"),	
				@NamedQuery(name="produtoPorNome",	
								query="SELECT	x	FROM	Produto	x	WHERE	x.nome	=	:nomeParam")	
})	
public	class	Produto	{	
				...	
}
EntityManager	em	=	...	
Query	q1	=	em.createNamedQuery("produtoMaisBarato");	
q1.setParameter(1,	10.0);	
List<Produto>	resultado1	=	q1.getResultList();		
Query	q2	=	em.createNamedQuery("produtoPorNome");	
q2.setParameter("nomeParam",	10.0);	
List<Produto>	resultado2	=	q2.getResultList();
Declarações (sintaxe)
• SELECT
cláusula_select cláusula_from

[cláusula_where] [cláusula_group_by]
[cláusula_having] [cláusula_order_by]
• UPDATE
cláusula_update
• DELETE
cláusula_delete

Sintaxe elementar
SELECT p.nome
FROM Produto AS p
WHERE p.codigo = '123'
Declara variável p como
sendo um Produto
O que vai ser
selecionado
Parâmetro
SELECT OBJECT (p) 

FROM Produto p 

WHERE p.nome = :n
AS é
opcional
Parâmetro do
método
Objeto (bean) sendo
selecionado
Palavras-chave JPQL
• Usadas na cláusula SELECT
– DISTINCT, OBJECT, AVG, MAX, MIN, SUM, COUNT
• Usadas na cláusula FROM
– IN, AS
• Usadas na cláusula WHERE
– FROM, WHERE, UPDATE, DELETE, JOIN, OUTER, INNER, LEFT,
GROUP, BY, HAVING, FETCH, OBJECT, NULL, TRUE, FALSE,
NOT, AND, OR, BETWEEN, LIKE, IN, AS, UNKNOWN, EMPTY,
MEMBER, OF, IS, ORDER, BY, ASC, DESC, MOD, UPPER,
LOWER, TRIM, POSITION, CHARACTER_LENGTH,
CHAR_LENGTH, BIT_LENGTH, CURRENT_TIME,
CURRENT_DATE, CURRENT_TIMESTAMP, NEW, EXISTS, ALL,
ANY, SOME
Cláusula FROM
• A cláusula FROM é quem informa o objeto
que está sendo pesquisado, e declara
variáveis usados no resto do query
– Cada variável tem um identificador e um tipo
– O identificador é qualquer palavra não-reservada
– O tipo é a classe do objeto marcado como @Entity
– A palavra-chave AS conecta o tipo ao identificador,
mas é opcional
FROM Produto AS p
Tipo Identificador
Cláusula SELECT
• A cláusula SELECT informa o que se deseja obter com
a pesquisa. Pode retornar
– Objetos (interfaces locais ou remotas)
– Atributos dos objetos
• A palavra SELECT pode ser seguida de DISTINCT para
eliminar valores duplicados nos resultados
• SELECT utiliza uma variável declarada na cláusula
FROM (opcionalmente pode usar OBJECT(p))
• Exemplos
SELECT p FROM Produto p
SELECT DISTINCT p FROM Produto p
SELECT p.codigo FROM Produto p
SELECT DISTINCT p.codigo FROM Produto p
Retorna
objetos
Retorna
campos
Cláusula WHERE
• A cláusula WHERE é opcional e restringe os resultados
da pesquisa com base em uma ou mais expressões
condicionais concatenadas
• As expressões podem usar
– Literais (strings, booleanos ou números)
– Identificadores (declarados no FROM)
– Operadores
– Funções
– Parâmetros do método que utiliza a pesquisa (?1, ?
2, :nome, ...)
• Literais
– Strings são representados entre apóstrofes: 'nome'
– Números têm mesmas regras de literais Java long e double
– Booleanos são TRUE e FALSE (case-insensitive)
Operadores
• Expressões matemáticas
– +, -, *, /
• Expressões de comparação
– =, >, >=, <, <=, <>
• Operadores lógicos
– NOT, AND, OR
• Outros operadores
– BETWEEN, NOT BETWEEN
– IN, NOT IN
– LIKE, NOT LIKE
– NULL, NOT NULL
– IS EMPTY, IS NOT EMPTY
– MEMBER, NOT MEMBER
• Operadores do LIKE
– _ representa um único caractere
– % representa uma seqüência de zero ou mais caracteres
–  caractere de escape (necessário para usar _ ou %) literalmente
Algumas funções
• Manipulação de strings (usados em WHERE)
– CONCAT, SUBSTRING, TRIM, LOWER, UPPER
– LENGTH, LOCATE
• Funções aritméticas (usados em WHERE)
– ABS, SQRT, MOD, SIZE
• Data e hora (usados em WHERE)
– CURRENT_DATE, CURRENT_TIME,
CURRENT_TIMESTAMP
• Funções de agregação (usados em SELECT)
– COUNT, MAX, MIN, AVG, SUM
Exemplos
• Encontre todos os produtos que são chips e cuja margem de
lucro é positiva
– SELECT p 

FROM Produto p 

WHERE (p.descricao = 'chip' 

AND (p.preco - p.custo > 0)
• Encontre todos os produtos cujo preço é pelo menos 1000 e no
máximo 2000
– SELECT p

FROM Produto p 

WHERE p.preco BETWEEN 1000 AND 2000
• Encontre todos os produtos cujo fabricante é Sun ou Intel
– SELECT p

FROM Produto p 

WHERE p.fabricante IN ('Intel', 'Sun')
Exemplos de JPA-QL (2)
• Encontre todos os produtos com IDs que começam com 12 e
terminam em 3
– SELECT p

FROM Produto p 

WHERE p.id LIKE '12%3'
• Encontre todos os produtos que têm descrições null
– SELECT p

FROM Produto p 

WHERE p.descricao IS NULL
• Encontre todos os pedidos que não têm itens (coleção)
– SELECT pedido FROM Pedido pedido WHERE pedido.itens
IS EMPTY
• Encontre todos os itens ligados a pedidos em coleção
– SELECT item

FROM Pedido pedido, Item item 

WHERE item IS MEMBER pedido.itens
9. Queries dinâmicos (JPA 2.0)
• Novidade	do	Java	EE	6	
– API	que	permite	a	construção	de	queries	usando	
objetos	
– Inspirado	em	Criteria	do	Hibernate	e	JDO	
– Pode-se	descobrir	erros	nos	queries	em	tempo	de	
compilação	
• Queries	são	mais	longos	e	podem	ser	mais	complexos,	mas	
podem	ser	alterados	dinamicamente	
• Ideal	para	formulários	de	pesquisa	onde	queries	são	
montados	de	acordo	com	preferências	do	usuário
Queries	dinâmicos	(JPA	2.0)
• Pode-se	montar	o	query	JPQL	
• usando	queries	dinâmicos,	da	seguinte	forma:
CriteriaBuilder qb =
em.getCriteriaBuilder();
CriteriaQuery<Produto> cq =
qb.createQuery(Produto.class);
Root<Produto> raiz = cq.from(Produto.class)
Predicate condicao =
qb.lt(raiz.get(Produto_.preco), 50.0);
cq.where(condicao);
TypedQuery<Person> query = em.createQuery(cq);
List<Produto> resultado = query.getResultList();
select p from Produto p where p.preco < 50.0
10. DAO para JPA em EJB 3
• JPA	não	precisa	de	DAO	quando	usado	em	EJB	3,	que	
cuida	dos	contextos	transacionais	
• Mas	um	DAO	ainda	é	importante	
– Camada	de	persistência	não	precisa	ser	JPA	(pode	
ser	JDBC	direto	ou	usar	bancos	não	relacionais	
como	Redis)	
– Permite	isolar	queries	(dinâmicos	do	JPA	2	ou	JPQL)	
• Usando	Generics	pode-se	criar	uma	interface	abstrata	
reusável
DAO	abstrato
public abstract class AbstractFacade<T> {
private Class<T> entityClass;
protected abstract EntityManager getEntityManager();
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}
public void create(T entity) {
getEntityManager().persist(entity);
}
public void edit(T entity) {
getEntityManager().merge(entity);
}
public void remove(T entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
}
DAO	concreto
• Precisa	apenas	estender	DAO	abstrato	para	cada	entidade	que	
se	deseja	usar	
– Métodos	herdados	disponíveis	para	uso	pelos	clientes	(ex:	EJBs)
@Stateless
public class ProdutoFacade extends AbstractFacade<Produto> {
@PersistenceContext(unitName = "LojaVirtual")
private EntityManager em;
protected EntityManager getEntityManager() {
return em;
}
public ProdutoFacade() {
super(Produto.class);
}
}
Referências
• Material	consultado	na	elaboração	deste	capítulo	
– Oracle.	Especificação	JPA	2.0:	https://jcp.org/aboutJava/
communityprocess/final/jsr317/	e	Especificação	JPA	1.0	
– Apache	OpenJPA:	https://openjpa.apache.org/	
– JBoss.org.	Hibernate	Entity	Manager	User	Guide	http://
docs.jboss.org/hibernate/entitymanager	
– Christian	Bauer	e	Gavin	King.	Java	Persistence	with	Hibernate.	
Manning,	2007	e	edições	anteriores.	
– Oracle,	Eric	Jendrock	et	al.	Java	EE	6	Tutorial.	http://
docs.oracle.com/javaee/6/tutorial/doc/	e	edições	anteriores	
– Versões	anteriores	deste	curso

More Related Content

What's hot

55 New Features in Java SE 8
55 New Features in Java SE 855 New Features in Java SE 8
55 New Features in Java SE 8Simon Ritter
 
스프링처럼 JDBC 리팩터링하기
스프링처럼 JDBC 리팩터링하기 스프링처럼 JDBC 리팩터링하기
스프링처럼 JDBC 리팩터링하기 Chanwook Park
 
Introdução a JavaScript
Introdução a JavaScriptIntrodução a JavaScript
Introdução a JavaScriptBruno Catão
 
Node.js - #1 - Introdução - Rodrigo Branas
Node.js - #1 - Introdução - Rodrigo BranasNode.js - #1 - Introdução - Rodrigo Branas
Node.js - #1 - Introdução - Rodrigo BranasRodrigo Branas
 
MongoDB performance
MongoDB performanceMongoDB performance
MongoDB performanceMydbops
 
Persistência com JPA usando o NetBeans 7
Persistência com JPA usando o NetBeans 7Persistência com JPA usando o NetBeans 7
Persistência com JPA usando o NetBeans 7Claudio Martins
 
10 Java Script - Exemplos práticos
10 Java Script - Exemplos práticos10 Java Script - Exemplos práticos
10 Java Script - Exemplos práticosCentro Paula Souza
 
Java 10 Classes Abstratas Interfaces
Java 10 Classes Abstratas InterfacesJava 10 Classes Abstratas Interfaces
Java 10 Classes Abstratas InterfacesRegis Magalhães
 
Ksug2015 - JPA2, JPA 기초와매핑
Ksug2015 - JPA2, JPA 기초와매핑Ksug2015 - JPA2, JPA 기초와매핑
Ksug2015 - JPA2, JPA 기초와매핑Younghan Kim
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDBMike Dirolf
 
Domain driven design
Domain driven designDomain driven design
Domain driven designits_skm
 
Rest webservice ppt
Rest webservice pptRest webservice ppt
Rest webservice pptsinhatanay
 
Encapsulamento em Orientação a Objetos
Encapsulamento em Orientação a ObjetosEncapsulamento em Orientação a Objetos
Encapsulamento em Orientação a ObjetosDaniel Brandão
 
Banco de Dados I - Aula 10 - Banco de Dados Relacional (Modelo Físico)
Banco de Dados I - Aula 10 - Banco de Dados Relacional (Modelo Físico)Banco de Dados I - Aula 10 - Banco de Dados Relacional (Modelo Físico)
Banco de Dados I - Aula 10 - Banco de Dados Relacional (Modelo Físico)Leinylson Fontinele
 

What's hot (20)

55 New Features in Java SE 8
55 New Features in Java SE 855 New Features in Java SE 8
55 New Features in Java SE 8
 
스프링처럼 JDBC 리팩터링하기
스프링처럼 JDBC 리팩터링하기 스프링처럼 JDBC 리팩터링하기
스프링처럼 JDBC 리팩터링하기
 
Introdução a JavaScript
Introdução a JavaScriptIntrodução a JavaScript
Introdução a JavaScript
 
Node.js - #1 - Introdução - Rodrigo Branas
Node.js - #1 - Introdução - Rodrigo BranasNode.js - #1 - Introdução - Rodrigo Branas
Node.js - #1 - Introdução - Rodrigo Branas
 
MongoDB performance
MongoDB performanceMongoDB performance
MongoDB performance
 
JPA - Java Persistence API
JPA - Java Persistence APIJPA - Java Persistence API
JPA - Java Persistence API
 
Aula javascript
Aula  javascriptAula  javascript
Aula javascript
 
React - Introdução
React - IntroduçãoReact - Introdução
React - Introdução
 
Persistência com JPA usando o NetBeans 7
Persistência com JPA usando o NetBeans 7Persistência com JPA usando o NetBeans 7
Persistência com JPA usando o NetBeans 7
 
10 Java Script - Exemplos práticos
10 Java Script - Exemplos práticos10 Java Script - Exemplos práticos
10 Java Script - Exemplos práticos
 
Java 10 Classes Abstratas Interfaces
Java 10 Classes Abstratas InterfacesJava 10 Classes Abstratas Interfaces
Java 10 Classes Abstratas Interfaces
 
Ksug2015 - JPA2, JPA 기초와매핑
Ksug2015 - JPA2, JPA 기초와매핑Ksug2015 - JPA2, JPA 기초와매핑
Ksug2015 - JPA2, JPA 기초와매핑
 
Protocol buffers
Protocol buffersProtocol buffers
Protocol buffers
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDB
 
Domain driven design
Domain driven designDomain driven design
Domain driven design
 
Postgresql
PostgresqlPostgresql
Postgresql
 
Spring Data JPA
Spring Data JPASpring Data JPA
Spring Data JPA
 
Rest webservice ppt
Rest webservice pptRest webservice ppt
Rest webservice ppt
 
Encapsulamento em Orientação a Objetos
Encapsulamento em Orientação a ObjetosEncapsulamento em Orientação a Objetos
Encapsulamento em Orientação a Objetos
 
Banco de Dados I - Aula 10 - Banco de Dados Relacional (Modelo Físico)
Banco de Dados I - Aula 10 - Banco de Dados Relacional (Modelo Físico)Banco de Dados I - Aula 10 - Banco de Dados Relacional (Modelo Físico)
Banco de Dados I - Aula 10 - Banco de Dados Relacional (Modelo Físico)
 

Similar to Introdução a JPA (2010)

Bancos de Dados Orientados a Objetos
Bancos de Dados Orientados a ObjetosBancos de Dados Orientados a Objetos
Bancos de Dados Orientados a ObjetosGlaucio Scheibel
 
Processos iniciais do mapeamento OR
Processos iniciais do mapeamento ORProcessos iniciais do mapeamento OR
Processos iniciais do mapeamento ORNécio de Lima Veras
 
Três anos de Scala no NewsMonitor
Três anos de Scala no NewsMonitorTrês anos de Scala no NewsMonitor
Três anos de Scala no NewsMonitorFelipe Hummel
 
Banco de dados orientados a objetos
Banco de dados orientados a objetos Banco de dados orientados a objetos
Banco de dados orientados a objetos Raquel Machado
 
Bancos de Dados Orientados a Objeto
Bancos de Dados Orientados a ObjetoBancos de Dados Orientados a Objeto
Bancos de Dados Orientados a Objetoelliando dias
 
Javascript para CSharpers 4 - POO
Javascript para CSharpers 4 - POOJavascript para CSharpers 4 - POO
Javascript para CSharpers 4 - POOWesley Lemos
 
Conexão Java 2006: Introdução ao Ajax
Conexão Java 2006: Introdução ao AjaxConexão Java 2006: Introdução ao Ajax
Conexão Java 2006: Introdução ao AjaxHelder da Rocha
 
Mapeamento Objeto Relacional em PHP com Outlet ORM
Mapeamento Objeto Relacional em PHP com Outlet ORMMapeamento Objeto Relacional em PHP com Outlet ORM
Mapeamento Objeto Relacional em PHP com Outlet ORMFábio Rehm
 
Padrões de projeto - Martin Fowler - P of EAA
Padrões de projeto - Martin Fowler - P of EAAPadrões de projeto - Martin Fowler - P of EAA
Padrões de projeto - Martin Fowler - P of EAAAricelio Souza
 
Classes Java , JDBC / Swing / Collections
Classes Java , JDBC / Swing / Collections Classes Java , JDBC / Swing / Collections
Classes Java , JDBC / Swing / Collections Eduardo Carvalho
 
Linguagem de Programação Java para Iniciantes
Linguagem de Programação Java para IniciantesLinguagem de Programação Java para Iniciantes
Linguagem de Programação Java para IniciantesOziel Moreira Neto
 
L'esprit de l'escalier
L'esprit de l'escalierL'esprit de l'escalier
L'esprit de l'escalierGleicon Moraes
 

Similar to Introdução a JPA (2010) (20)

Bancos de Dados Orientados a Objetos
Bancos de Dados Orientados a ObjetosBancos de Dados Orientados a Objetos
Bancos de Dados Orientados a Objetos
 
Processos iniciais do mapeamento OR
Processos iniciais do mapeamento ORProcessos iniciais do mapeamento OR
Processos iniciais do mapeamento OR
 
Três anos de Scala no NewsMonitor
Três anos de Scala no NewsMonitorTrês anos de Scala no NewsMonitor
Três anos de Scala no NewsMonitor
 
Banco de dados orientados a objetos
Banco de dados orientados a objetos Banco de dados orientados a objetos
Banco de dados orientados a objetos
 
Apresentação mapeamento objeto relacional
Apresentação mapeamento objeto relacionalApresentação mapeamento objeto relacional
Apresentação mapeamento objeto relacional
 
Bancos de Dados Orientados a Objeto
Bancos de Dados Orientados a ObjetoBancos de Dados Orientados a Objeto
Bancos de Dados Orientados a Objeto
 
MAC5855 - NoSQL
MAC5855 - NoSQLMAC5855 - NoSQL
MAC5855 - NoSQL
 
Aula1
Aula1Aula1
Aula1
 
Javascript para CSharpers 4 - POO
Javascript para CSharpers 4 - POOJavascript para CSharpers 4 - POO
Javascript para CSharpers 4 - POO
 
Conexão Java 2006: Introdução ao Ajax
Conexão Java 2006: Introdução ao AjaxConexão Java 2006: Introdução ao Ajax
Conexão Java 2006: Introdução ao Ajax
 
Mapeamento Objeto Relacional em PHP com Outlet ORM
Mapeamento Objeto Relacional em PHP com Outlet ORMMapeamento Objeto Relacional em PHP com Outlet ORM
Mapeamento Objeto Relacional em PHP com Outlet ORM
 
2006 - ADONET.ppt
2006 - ADONET.ppt2006 - ADONET.ppt
2006 - ADONET.ppt
 
Java 02
Java 02Java 02
Java 02
 
DDD > Experiências
DDD > ExperiênciasDDD > Experiências
DDD > Experiências
 
Padrões de projeto - Martin Fowler - P of EAA
Padrões de projeto - Martin Fowler - P of EAAPadrões de projeto - Martin Fowler - P of EAA
Padrões de projeto - Martin Fowler - P of EAA
 
5 bdoo+bdor
5 bdoo+bdor5 bdoo+bdor
5 bdoo+bdor
 
Classes Java , JDBC / Swing / Collections
Classes Java , JDBC / Swing / Collections Classes Java , JDBC / Swing / Collections
Classes Java , JDBC / Swing / Collections
 
Linguagem de Programação Java para Iniciantes
Linguagem de Programação Java para IniciantesLinguagem de Programação Java para Iniciantes
Linguagem de Programação Java para Iniciantes
 
POO - Aula 003
POO - Aula 003POO - Aula 003
POO - Aula 003
 
L'esprit de l'escalier
L'esprit de l'escalierL'esprit de l'escalier
L'esprit de l'escalier
 

More from Helder da Rocha

Como criar um mapa temático interativo com dados abertos e D3.js
Como criar um mapa temático interativo com dados abertos e D3.jsComo criar um mapa temático interativo com dados abertos e D3.js
Como criar um mapa temático interativo com dados abertos e D3.jsHelder da Rocha
 
Transforming public data into thematic maps (TDC2019 presentation)
Transforming public data into thematic maps (TDC2019 presentation)Transforming public data into thematic maps (TDC2019 presentation)
Transforming public data into thematic maps (TDC2019 presentation)Helder da Rocha
 
TDC 2019: transformando 
dados
públicos
em mapas interativos
TDC 2019: transformando 
dados
públicos
em mapas interativosTDC 2019: transformando 
dados
públicos
em mapas interativos
TDC 2019: transformando 
dados
públicos
em mapas interativosHelder da Rocha
 
Padrões essenciais de mensageria para integração de sistemas
Padrões essenciais de mensageria para integração de sistemasPadrões essenciais de mensageria para integração de sistemas
Padrões essenciais de mensageria para integração de sistemasHelder da Rocha
 
Visualização de dados e a Web
Visualização de dados e a WebVisualização de dados e a Web
Visualização de dados e a WebHelder da Rocha
 
Eletrônica Criativa: criando circuitos com materiais alternativos
Eletrônica Criativa: criando circuitos com materiais alternativosEletrônica Criativa: criando circuitos com materiais alternativos
Eletrônica Criativa: criando circuitos com materiais alternativosHelder da Rocha
 
Introdução à Visualização de Dados (2015)
Introdução à Visualização de Dados (2015)Introdução à Visualização de Dados (2015)
Introdução à Visualização de Dados (2015)Helder da Rocha
 
Minicurso de Segurança em Java EE 7
Minicurso de Segurança em Java EE 7Minicurso de Segurança em Java EE 7
Minicurso de Segurança em Java EE 7Helder da Rocha
 
Curso de WebServlets (Java EE 7)
Curso de WebServlets (Java EE 7)Curso de WebServlets (Java EE 7)
Curso de WebServlets (Java EE 7)Helder da Rocha
 
Atualização Java 8 (2014)
Atualização Java 8 (2014)Atualização Java 8 (2014)
Atualização Java 8 (2014)Helder da Rocha
 
Curso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e StreamsCurso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e StreamsHelder da Rocha
 
Threads 07: Sincronizadores
Threads 07: SincronizadoresThreads 07: Sincronizadores
Threads 07: SincronizadoresHelder da Rocha
 
Threads 08: Executores e Futures
Threads 08: Executores e FuturesThreads 08: Executores e Futures
Threads 08: Executores e FuturesHelder da Rocha
 
Threads 06: Coleções concorrentes
Threads 06: Coleções concorrentesThreads 06: Coleções concorrentes
Threads 06: Coleções concorrentesHelder da Rocha
 
Threads 05: Travas de Exclusão Mútua
Threads 05: Travas de Exclusão MútuaThreads 05: Travas de Exclusão Mútua
Threads 05: Travas de Exclusão MútuaHelder da Rocha
 
Threads 04 Variáveis atômicas
Threads 04 Variáveis atômicasThreads 04 Variáveis atômicas
Threads 04 Variáveis atômicasHelder da Rocha
 
Threads 03: Ciclo de vida, aplicações e boas práticas
Threads 03: Ciclo de vida, aplicações e boas práticasThreads 03: Ciclo de vida, aplicações e boas práticas
Threads 03: Ciclo de vida, aplicações e boas práticasHelder da Rocha
 

More from Helder da Rocha (20)

Como criar um mapa temático interativo com dados abertos e D3.js
Como criar um mapa temático interativo com dados abertos e D3.jsComo criar um mapa temático interativo com dados abertos e D3.js
Como criar um mapa temático interativo com dados abertos e D3.js
 
Transforming public data into thematic maps (TDC2019 presentation)
Transforming public data into thematic maps (TDC2019 presentation)Transforming public data into thematic maps (TDC2019 presentation)
Transforming public data into thematic maps (TDC2019 presentation)
 
TDC 2019: transformando 
dados
públicos
em mapas interativos
TDC 2019: transformando 
dados
públicos
em mapas interativosTDC 2019: transformando 
dados
públicos
em mapas interativos
TDC 2019: transformando 
dados
públicos
em mapas interativos
 
Padrões essenciais de mensageria para integração de sistemas
Padrões essenciais de mensageria para integração de sistemasPadrões essenciais de mensageria para integração de sistemas
Padrões essenciais de mensageria para integração de sistemas
 
Visualização de dados e a Web
Visualização de dados e a WebVisualização de dados e a Web
Visualização de dados e a Web
 
Eletrônica Criativa: criando circuitos com materiais alternativos
Eletrônica Criativa: criando circuitos com materiais alternativosEletrônica Criativa: criando circuitos com materiais alternativos
Eletrônica Criativa: criando circuitos com materiais alternativos
 
Introdução à Visualização de Dados (2015)
Introdução à Visualização de Dados (2015)Introdução à Visualização de Dados (2015)
Introdução à Visualização de Dados (2015)
 
Java 9, 10, 11
Java 9, 10, 11Java 9, 10, 11
Java 9, 10, 11
 
Minicurso de Segurança em Java EE 7
Minicurso de Segurança em Java EE 7Minicurso de Segurança em Java EE 7
Minicurso de Segurança em Java EE 7
 
Curso de WebServlets (Java EE 7)
Curso de WebServlets (Java EE 7)Curso de WebServlets (Java EE 7)
Curso de WebServlets (Java EE 7)
 
Curso de Java: Threads
Curso de Java: ThreadsCurso de Java: Threads
Curso de Java: Threads
 
Atualização Java 8 (2014)
Atualização Java 8 (2014)Atualização Java 8 (2014)
Atualização Java 8 (2014)
 
Curso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e StreamsCurso de Java: Introdução a lambda e Streams
Curso de Java: Introdução a lambda e Streams
 
Threads 07: Sincronizadores
Threads 07: SincronizadoresThreads 07: Sincronizadores
Threads 07: Sincronizadores
 
Threads 09: Paralelismo
Threads 09: ParalelismoThreads 09: Paralelismo
Threads 09: Paralelismo
 
Threads 08: Executores e Futures
Threads 08: Executores e FuturesThreads 08: Executores e Futures
Threads 08: Executores e Futures
 
Threads 06: Coleções concorrentes
Threads 06: Coleções concorrentesThreads 06: Coleções concorrentes
Threads 06: Coleções concorrentes
 
Threads 05: Travas de Exclusão Mútua
Threads 05: Travas de Exclusão MútuaThreads 05: Travas de Exclusão Mútua
Threads 05: Travas de Exclusão Mútua
 
Threads 04 Variáveis atômicas
Threads 04 Variáveis atômicasThreads 04 Variáveis atômicas
Threads 04 Variáveis atômicas
 
Threads 03: Ciclo de vida, aplicações e boas práticas
Threads 03: Ciclo de vida, aplicações e boas práticasThreads 03: Ciclo de vida, aplicações e boas práticas
Threads 03: Ciclo de vida, aplicações e boas práticas
 

Introdução a JPA (2010)

  • 2. Conteúdo • 1. Relacionamento entre objetos (revisão) • 2. Mapeamento objeto relacional • 3. Introdução prática • 4. Mapeamento básico de entidades • 5. Mapeamento de associações • 6. Mapeamento de componentes • 7. Mapeamento de entidades em herança • 8. Queries JPQL • 9. Queries Criteria (JPA 2 / Java EE 6) • 10. DAO genérico
  • 3. 1. Relacionamento entre objetos • Relacionamentos e objetos • Tipos de relacionamento • Cardinalidade • Direção e visibilidade • Exemplos
  • 4. Relacionamentos Produto Item Pedido Cliente FachadaLoja FachadaLojaMemoria Serviços Entidades **
  • 5. Objetos que são coisas: entidades • Interface para dados: estado • Classes geralmente possuem várias instâncias, claramente identificadas • Business Objects • Produtos, Itens, Pedidos, Clientes • Métodos operam sobre seus próprios dados e sobre objetos dependentes
  • 6. Objetos que fazem coisas: serviços • Interface para operações: comportamento • Classes geralmente representam uma única instância (singleton) • Dados (estado) compartilhados • Application Services • Fachadas, DAOs, Serviços, Camadas • Métodos utilizam entidades e outros serviços para realizar casos de uso
  • 7. Tipos de relacionamento • Ligação fraca: uso / associação – Navio / Porto: porto existe sem navio e navio existe sem porto e a destruição de um não afeta o outro – Porto e Navio devem ter interfaces compatíveis (para permitir que Navio possa atracar) • Ligação forte: agregação – Navio / Carga: cada container de carga acrescenta (agrega) algo ao navio – Cascade-delete: se navio afundar, a carga vai junto • Ligação muito forte: composição – Navio / Casco: o navio não pode ser utilizado (inicializado) sem que seu casco esteja pronto antes
  • 8. Em Java: associação • Associação bidirecional (porto conhece seus navios e cada navio sabe em que porto está) class Porto { private Set navios = new Set(); public Porto() {} public void addNavio(Navio n) { navios.add(n); n.atracar(this); } public Set getNavios() { return navios; } } class Navio { Porto porto; public Navio() {} public void atracar(Porto p) { porto = p; } public boolean atracado() { return porto != null; } }
  • 9. Em Java: agregação class Carga { private double peso; public Carga(double p) { peso = p; } public double getPeso() { return peso; } public double destruir() { peso = 0.0; } } class Navio { private Set<Carga> containers; private double peso = 100.0; public Navio() {} public void carregar(Carga c) { containers.add(c); } public void afundar() { for(Carga c: carga) carga.destruir(); } public double pesar() { for(Carga c: carga) { peso += carga.getPeso(); } } Agregação unidirecional (navio conhece suas cargas, mas Carga desconhece em que navio está)
  • 10. Em Java: composição class Estaleiro { private Navio montar() { Casco c = new CascoLongo(); Leme m = new LemeHidraulico(); return new Navio(c, m); } } class Navio { private Casco casco; private Leme leme; public Navio(Casco c, Leme m) { casco = c; leme = m; } public void virarDireita() { leme.virarEsquerda(); } public void virarEsquerda() { leme.virarDireita(); } } class CascoLongo implements Casco { int comprimento = 100; int largura = 10; } abstract class Leme { abstract void virarEsquerda(); abstract void virarDireita(); } . . .
  • 11. Cardinalidade • Um para muitos, bidirecional • Um para um, bidirecional • Muitos para muitos, bidirecional class Produto { Item item; } class Item { Produto produto; } class Pedido { Set<Item> itens; } class Item { Pedido pedido; } class Aluno { Set<Turma> turmas; } class Turma { Set<Aluno> alunos; } Os atributos representam estados visíveis (métodos get/ set)
  • 12. Direção e visibilidade • Um para muitos, unidirecional • Muitos para um, unidirecional • Um para um, unidirecional class Produto { } class Item { Produto produto; } class Pedido { Set<Item> itens; } class Item { } class Pedido { } class Item { Pedido pedido; } equivalentes
  • 13. 2. Introdução ao mapeamento objeto relacional (ORM) • O que é ORM e como funciona? • Dificuldades da ORM: incompatibilidades • Usando uma camada de persistência JDBC • Exemplo: tabelas e objetos + DAO
  • 14. O que é ORM • Object Relational Mapping • Mapeamento de classes a esquemas de bancos de dados relacionais – Em tempo de configuração • Utilização de uma API de persistência – Em tempo de desenvolvimento • Persistência transparente de objetos como registros de um banco de dados – Em tempo de execução
  • 15. Por que usar ORM? • Facilitar o desenvolvimento – Simplificar, facilitar manutenção – Separar responsabilidades • Unir os benefícios de dois mundos – Preservar as vantagens do paradigma relacional (robustez, maturidade, facilidade de pesquisa, etc.) para a camada de persistência – Preservar as vantagens do paradigma orientado a objetos (reuso, modularidade, herança, polimorfismo, etc.) para a camada de negócios
  • 16. Como funciona? • Tempo de configuração – Classes mapeadas a tabelas (esquemas) • Tempo de execução – Instâncias (objetos) automaticamente mapeadas a registros conta correntista saldo 1 Gargantua 1370 2 Pantagruel 3450 3 Gargamel 800 4 Morticia 8200 Classe Conta String codigo String nome double saldo instância:Conta codigo="4" nome="Morticia" saldo=8200 Tabela Conta Banco de Dados Relacional
  • 17. Mas... • Nem sempre o modelo relacional é equivalente ao modelo de objetos – O modelo normalizado mais eficiente geralmente tem menos tabelas que os objetos do modelo de objetos mais bem projetado – Há objetos dependentes que são parte de um objeto maior (colunas de uma tabela) – Há objetos que são apenas visões de dados (dados de várias tabelas) • Uma boa ferramenta de ORM permite configurar essas incompatibilidades
  • 18. Mapeamento ideal • Neste exemplo, o descasamento entre o paradigma objeto e relacional não aparece public class Cliente { private String userid; private String nome; private String endereco; private Set contas; // (get/set), etc. ... } public class Conta { private String numero; private String nome; private String tipo; private Cliente usuario; // métodos, get/set... } create table CLIENTE ( USERID VARCHAR(15) NOT NULL PRIMARY KEY, NOME VARCHAR(50) NOT NULL, ENDERECO VARCHAR(100) ) create table CONTA ( NUMERO VARCHAR(10) NOT NULL PRIMARY Key, NOME VARCHAR(50) NOT NULL, TIPO VARCHAR(2) NOT NULL, USUARIO VARCHAR(15) FOREIGN KEY REFERENCES CLIENTE ) Foreign key USUARIO realiza o relacionamento
  • 19. Problema: granularidade • Vários níveis são possíveis no modelo de objetos – Baixa: Cliente com endereco (String) – Mais alta: Endereco é objeto com propriedades: como cep, cidade, rua, país, etc. – Ainda mais alta: Rua é objeto com propriedades numero, etc. • Há dois níveis apenas no modelo relacional – Tabela (CLIENTE) e coluna (USERID, ENDERECO, etc.) • Solução: múltiplos objetos mapeados a uma tabela create table CLIENTE ( USERID VARCHAR(15) NOT NULL PRIMARY KEY, NOME VARCHAR(50) NOT NULL, ENDERECO_RUA VARCHAR(50), ENDERECO_CIDADE VARCHAR(15), ENDERECO_ESTADO VARCHAR(15), ENDERECO_CEP VARCHAR(8), ENDERECO_PAIS VARCHAR(15) ) Cliente Endereco
  • 20. Problema: tipos e subtipos • Modelo relacional não suporta herança nem polimorfismo – Queremos escrever queries que referem-se à classe Conta e retornar instâncias concretas dessa classe! • Requer implementação bem mais complexa Associação polimórfica! Cliente Conta ContaCredito ContaDebito *
  • 21. Problema: identidade • No mundo relacional, existe um critério de igualdade: – Chave-primária • No mundo Java há dois – Igualdade de referência (testado com ==) – Equivalência (testado com equals()) • Além disso, mapeamento pode associar vários objetos a uma mesma tabela! • Complicações adicionais e problemas – Chaves naturais – Chaves compostas – Ausência de chave – Chaves que podem ser modificadas problema de design: deve ser corrigido devem ser evitadas em sistemas novos
  • 22. Problema: associações • Java representa associações como referências (ou coleções de) referências para objetos – São inerentemente direcionais – Para implementar associações bidirecionais, é preciso criar referências dos dois lados da associação – Referências duplas podem ser associações M-N • No mundo relacional, associações são representadas por chaves estrangeiras – Não são inerentemente direcionais – Pode-se criar associações com projeção e joins – Associações M-N requerem tabela extra
  • 23. Problema: navegação em grafos • Navegação em objetos – Pula-se de um objeto para outro: obj.getA().getB() sem que haja um caminho previamente definido – O equivalente em SQL seria fazer um query para cada pulo (nó do grafo) – Portanto, a forma mais natural de navegar entre objetos em OO é a forma menos eficiente de recuperar dados em SQL • Joins podem minimizar queries – Mas perde-se a flexibilidade da definição dinâmica do caminho de navegação
  • 24. Solução • Usar uma camada de persistência para lidar com incompatibilidades entre os paradigmas – Usar uma arquitetura com separação em camadas – Cada camada concentra-se em um interesse predominante – Uma das camadas cuida da persistência • Como implementar – Escrever uma camada de persistência (ex: DAO JDBC) – Usar uma solução como ORM 
 (ex: Hibernate) Camada de Apresentação Camada de Negócios Camada de Persistência
  • 25. 3. Introdução prática: Hello World • Passo-a-passo na construção de uma aplicação JPA simples – Criação de um projeto – Criação dos objetos e das tabelas – Definição dos mapeamentos – Configuração do ambiente – Implementação da persistência • Siga os passos na sua máquina
  • 26. Criação do projeto • Crie um novo projeto no NetBeans – Pacote raiz: jpaloja • Dependências – Inclua todos os JARs do diretório lib/ da distribuição do Hibernate – Inclua o driver JDBC do banco de dados • Crie uma base de dados “aula” no MySQL – Anote também o nome de usuário e senha para acesso ao banco de dados
  • 27. Próximos passos • Criar tabela no banco – Opcional: nós vamos gerar a tabela a partir do próprio objeto Java anotado • Criar o objeto (POJO) • Criar as anotações de mapeamento entre o POJO e a tabela (três anotações) • Configuração – Criar arquivo de configuração da persistência (persistence.xml) • Utilização – Implementar classe de testes e usar a API
  • 28. Regras para construção de POJOs • Regras para construção de JavaBeans – Construtor sem argumentos com visibilidade mínima de pacote – Expor estado usando métodos get/set • Exemplo: para propriedade do tipo String “texto” use – String getTexto() e – void setTexto(String texto) • Métodos get/set devem seguir as convenções JavaBean mas não precisam ser públicos – O JPA enxerga os métodos private • Métodos get/set a outras entidades determinam associações e permitem navegação no grafo de objetos
  • 29. Identidade • O objeto que será mapeado via JPA deve ter um campo que possa ser usado como identificador – Independente do objeto já ter algum atributo unívoco (como userid) • Deve ser um campo inteiro numérico (int, Integer, long, Long) – Será usado pelo JPA para controlar a persistência
  • 30. POJO: classe Produto package jpaloja.pojos; public class Produto { private Long codigo; private String nome; private double preco; public Produto() { } // construtor vazio (necessário) public Produto(String nome, double preco) { this.nome = nome; this.preco = preco; } public Long getCodigo() { return codigo; } private void setCodigo(Long codigo) { this.codigo = codigo; } // outros métodos get/set (...) } Crie o POJO no pacote jpaloja.pojos O Netbeans guardará na pasta src do projeto O Netbeans gera automaticamente o construtor utilitário (com argumentos) e os métodos get/set
  • 31. Tabela • Iremos mapear o Produto à seguinte tabela • Não precisa criar a tabela neste momento pois iremos gerá-la CREATE TABLE produto ( codigo int8 NOT NULL, preco float8, nome varchar(255), CONSTRAINT produto_pkey PRIMARY KEY (codigo) )
  • 32. Mapeamento • Acrescente as seguintes anotações de mapeamento no arquivo Produto.java package jpaloja.pojos; import javax.persistence.*; @Entity public class Produto { @Id @GeneratedValue (strategy=GenerationType.AUTO) private Long codigo; ... }
  • 33. Mapeamento: tabelas e classes • O mapeamento da classe à tabela é realizada através da anotação @Entity – Se o nome da tabela não for informado, ela terá o mesmo nome que a classe package jpaloja.pojos; import javax.persistence.*; @Entity @Table(name = “PRODUTO”) public class Produto { ... }
  • 34. Mapeamento: identificador • O identificador é mapeado através da anotação @Id à chave primária da tabela • A anotação @GeneratedValue informa como a chave será incrementada pelo provedor de persistência package jpaloja.pojos; import javax.persistence.*; @Entity public class Produto { @Id @GeneratedValue (strategy=GenerationType.AUTO) private Long codigo; }
  • 35. Mapeamento: propriedades • As propriedades escalares são mapeadas através da anotação @Column – Se ela for omitida, todos os métodos automaticamente serão considerados parte da interface de mapeamento @Entity @Table(name = “PRODUTO”) public class Produto { @Column(name = “CODIGO”) private Long codigo; @Column(name = “NOME”) private String nome; @Column(name=”PRECO”) private double preco; }
  • 36. Configuração da persistência <?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" ... > <persistence-unit name="LojaVirtual"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <!-- <jta-data-source>java:/LojaVirtualDS</jta-data-source> --> <class>lojavirtual.Produto</class> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> <property name="hibernate.connection.username" value="root"/> <property name="hibernate.connection.password" value=""/> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/test"/> <property name="hibernate.transaction.manager_lookup_class" 
 value="org.hibernate.transaction.JBossTransactionManagerLookup"/> <property name="hibernate.show_sql" value="true"/> <!-- <property name="hibernate.hbm2ddl.auto" value="create"/> --> </properties> </persistence-unit> </persistence> Descomente na primeira execução para gerar as tabelas, depois comente de novo. Guarde em src/META-INF com o nome persistence.xml
  • 37. Utilização da persistência • Para usar o mecanismo de persistência do JPA, é preciso inicializar uma sessão do EntityManager – O EntityManager oferece uma API de operações de persistência (gravação, leitura, transações) – Cada sessão ocupa um thread e é obtida a partir de um EntityManagerFactory ou via injeção de dependências (em EJB 3) • No nosso exemplo usaremos EJB 3 – Será preciso criar um EJB (Session Bean) para gerenciar a persistência, e disponibilizá-lo no JBoss
  • 38. Principais interfaces • Todas do pacote javax.persistence • Persistence – Oferece um factory method para criar EMF • EntityManagerFactory – Equivalente a SessionFactory do Hibernate • EntityManager – Equivalente a Session do Hibernate • Query – Equivalente a Query do Hibernate • EntityTransaction – Equivalente a Transaction do Hibernate
  • 39. Alguns métodos de EntityManager • void persist(E objeto) – Insere objeto na camada de persistência • E find(E.class, Object id) – Localiza objeto pelo ID • E merge(E objeto) – Atualiza objeto (e cascade, se houver) • Query createQuery(String jpql) – Cria um query • Outros: – remove(E objeto), flush(), close(), getTransaction()
  • 40. Inserir package loja; import jpaloja.pojos.Produto; import javax.persistence.*; public class Inserir { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("LojaVirtual"); EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); Produto p1 = new Produto("Giroscopio", 123.89); Produto p2 = new Produto("Tesoura", 23.14); em.persist(p1); em.persist(p2); tx.commit(); em.close(); } }
  • 41. Listar package loja; public class Listar { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("LojaVirtual"); EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); Query q = em.createQuery("select p from Produto p”); List produtos = q.getResultList(); System.out.println( produtos.size() + “ produtos encontrados!”); for (Object o: produtos.getResultList()) { Produto p = (Produto) o; System.out.println( p.getNome() + “ $” + p.getPreco() ); } tx.commit(); em.close(); } }
  • 42. SessionContext do EJB • Para obter, use injeção de recursos @Resource
 SessionContext ctx; • A partir do contexto, pode-se localizar objetos e recursos via JNDI DataSource ds = ctx.lookup("java:/DefaultDS"); EntityManagerFactory emf = ctx.lookup("emf/loja"); Queue fila = ctx.lookup("jms/Queue"); • É melhor obter um EntityManager usando injeção de recursos com @PersistenceContext @PersistenceContext private EntityManager em;
  • 43. EJB usando persistência @Stateless public class ProdutoFacadeBean implements ProdutoFacadeBeanRemote { @PersistenceContext(unitName="LojaVirtual") private EntityManager em; public List<Produto> retrieveAll() { Query query = em.createQuery("select p from Produto p"); List<Produto> produtos = query.getResultList(); return produtos; } public Produto insert(Produto p) { em.persist(p); return em.merge(p); } ...
  • 44. Execução • Isto é um cliente EJB remoto – Sua execução requer a configuração de um cliente Java EE (contendo JARs / client do JBoss + jndi.properties informando a localização do servidor) public class ProdutoTest { public static void main(String[] args) throws NamingException { ProdutoFacadeBeanRemote facade; Context jndi = new InitialContext(); Object obj = jndi.lookup("ProdutoFacadeBean/remote"); facade = (ProdutoFacadeBeanRemote) obj; Produto p1 = new Produto(); p1.setNome("Produto 1"); p1.setPreco(30.00); Produto p2 = new Produto(); p2.setNome("Produto 2"); p2.setPreco(50.00); facade.insert(p1); facade.insert(p2); ...
  • 45. JP-QL • JP Query Language é um dialeto orientado a objetos do SQL – Não é uma linguagem de manipulação de dados (como SQL) – Não serve para inserir, remover, atualizar (tem como fazer, mas não se recomenda) – É usada apenas para recuperação de objetos • Exemplo Query q = 
 session.createQuery("select u from User u where u.firstname = :fname"); q.setString("fname", "Max"); List result = q.getResultList();
  • 46. 4. Mapeamento de entidades • A classe deve ser descrita como entidade – anotada com @Entity (ou declarada como <entity> no deployment descriptor orm.xml) – ter um campo @Id (a menos que participe como subclasse de uma hierarquia mapeada em JPA) • Deve ter construtor sem argumentos • Não pode – ser interface ou um enum ou classe final – ter variáveis de instância ou métodos finais • Deve implementar java.io.Serializable se precisar ser passada por valor – Ex: se objeto for usado por um cliente remoto, como em EJBs que têm interface @Remote
  • 47. Entidades • Suportam herança, associações polimórficas, queries polimórficos – Podem estender classes comuns e vice-versa – Somente entidades podem ser usadas em queries JPA • Seu estado persistente é representado pelas suas variáveis de instância – acessado via propriedades (métodos get/set) ou através de suas variáveis de instância – variáveis de instância não declaradas transient e que não tenham a anotação @Transient são consideradas persistentes.
  • 48. Entidades • Assinaturas válidas para propriedades: – Propriedades escalares (value-types) ou lado unitário de associações com entidades (@Column):
 T getProperty() e void setProperty(T t) – Coleções de escalares (value-types) ou lado múltiplo de associações com entidades (@JoinColumn)
 Set<T> getProperty() e void setProperty(Set<T>) 
 (ou Collection, List ou Map) • Tipos permitidos: – Value-types: primitivos, String, BigInteger, BigDecimal, Date, Calendar, Time, Timestamp, byte[], Byte[], char, Character[], enums e coleções desses valores – Tipos serializáveis e coleções de tipos serializáveis – Entidades e coleções de entidades
  • 49. Exemplo de mapeamento @Entity public class Cliente implements Serializable { @Id private Long id; private String nome; private Endereco endereco; @OneToMany private Set<Pedido> pedidos = new HashSet(); @ManyToMany private Set<Pagamento> formasPagamento = new HashSet(); public Cliente() {} public Long getId() { return id; } public void setId(Long id) { this.id = id; } ... public Collection<Order> getPedidos() { return pedidos; } public void setPedidos(Collection<Pedido> pedidos) { this.pedidos = pedidos; } public Set<Pagamento> getFormasPagamento() { return formasPagamento; } ... } Usando o mínimo de anotações! Anotações ausentes (ex: @Column, @Table, etc.) resultam em comportamento default (ex: tabela com mesmo nome que classe) As anotações também possuem muitas propriedades que podem ser configuradas; se omitidas, são usadas as propriedades default
  • 50. Ciclo de vida de uma entidade: 
 breve resumo • A operação new cria uma instância no estado transiente – Entidade transiente = new Entidade() • Para tornar a instância persistente é preciso utilizar a API do EntityManager – entityManager.persist(transiente); – Entidade persistente = entityManager.merge(transiente); • Toda entidade tem uma chave primária. – Indicada pela anotação @Id (pode ser na superclasse) e geralmente definida pelo serviço de persistência – Aplicação nunca deve mudar valor de chave primária. • Fora do escopo do EntityManager, objeto que já foi persistente é considerado desconectado (detached) – Pode ser re-ligado com um merge:
 Entidade persistente = entityManager.merge(detached);
  • 51. 5. Mapeamento de associações • Associações no JPA funcionam da mesma maneira que associações de objetos em Java – Associações de objetos em JPA são naturalmente unidirecionais e não são gerenciadas pelo container (como em EJB 2.1) • Associações são sempre relacionamentos entre entidades (diretamente ou via coleções) • Três tipos – @OneToOne – @ManyToOne – @ManyToMany • Duas possibilidades para cada tipo – Unidirecional – Bidirecional
  • 52. Associações • @ManyToOne é a associação mais comum – O modelo relacional é naturalmente um-para-muitos – Uma referência simples de objeto é um-para-muitos – Em associações bidirecionais, do outro lado deve haver @OneToMany • @OneToOne requer constraints (que são gerados) nas tabelas para garantir consistência da associação • @ManyToMany mapeia três tabelas a dois objetos • Em associações bidirecionais, há anotações de ambos os lados – Atributo mappedBy é usado em associações bidirecionais para informar o nome do atributo da outra classe que faz a associação – @OneToOne CPF cpf; 
 à @OneToOne(mappedBy="cpf") Cliente cliente; – @ManyToMany(mappedBy="alunos") Set<Turma> turmas; 
 à @ManyToMany(mappedBy="turmas") Set<Aluno> alunos; – @ManyToOne(mappedBy="item") Set<Produto> produtos; 
 à @OneToMany Item item;
  • 53. @ManyToOne • Pode-se mapear tudo com @ManyToOne • Associações @OneToOne são raras – Muitas vezes representam composições que devem ser preferivelmente implementadas usando @Embedded / @Embeddable (veremos na parte 3, adiante) • Associações @ManyToMany podem ser implementadas com três objetos e duas associações @ManyToOne – As vezes isto é mais simples e adequado, quando se precisa de um objeto mapeando a associação (join-table) • Várias anotações e atributos permitem configurar ajustes finos dos mapeamentos • Escolha a solução mais simples e adequada ao seu projeto
  • 54. ManyToOne unidirecional @Entity public class Produto { @Id @GeneratedValue int codigo; String nome; double preco; public int getCodigo() { return codigo; } public void setCodigo(int codigo) { this.codigo = codigo; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } ... @Entity public class Item { @ManyToOne private Produto produto; public Produto getProduto() { return produto; } public void setProduto(Produto produto) { this.produto = produto; } public double subtotal() { return this.produto.getPreco() * this.quantidade; } ... Classe Produto não sabe da existência da associação* Método de negócio que utiliza-se da associação para realizar uma operação * Esses dados são insuficientes para a geração automática do esquema (as tabelas devem existir antes)
  • 55. ManyToOne bidirecional @Entity public class Pedido { @OneToMany(mappedBy="pedido") private Set<Item> itens = new HashSet<Item>(); public Set<Item> getItens() { return itens; } public void setItens(Set<Item> itens) { this.itens = itens; } public void addItem(Item item) { itens.add(item); item.setPedido(this); } public double subtotal() { double subtotal = 0; for (Item item : itens) { subtotal += item.subtotal(); } return subtotal; } ... @Entity public class Item { @ManyToOne private Pedido pedido; public Pedido getPedido() { return pedido; } public void setPedido(Pedido pedido) { this.pedido = pedido; } public double subtotal() { ... } ... Utilitário para facilitar a adiçção de itens na associação (atualiza os dois lados da associação) Método de negócio que utiliza-se da associação para realizar uma operação
  • 56. @ManyToMany • Default: @ManyToMany nos Set de cada lado da associação, informando o campo de mapeamento (mappedBy) – Em associações bidirecionais, é preciso atualizar os dois lados – Usando-se Set e mappedBy, garante-se a não duplicação de dados quando objeto é adicionado duas vezes na coleção • Muitos ajustes possíveis – Uso de List ou Collection (com ou sem @CollectionID) ou Map (com @MapKey) – Configuração de @JoinTable, @JoinColumn, @SecondaryTable • Essas configurações avançadas não serão abordadas neste curso
  • 58. @OneToOne • Muitas vezes é desnecessário -relacionamento pode ser representado de outras formas – Pode ser @ManyToOne unidirecional – Pode ser implementado com o componente na mesma tabela (@Embedded) • Duas formas de mapeamento @OneToOne – Associação de chave estrangeira (default) – Associação de chave primária (não pode definir um @JoinColumn, mas é anotado com @PrimaryKeyJoinColumn • Neste curso utilizaremos apenas o mapeamento default
  • 60. Cascades: persistência transitiva • Para acrescentar um item em um pedido, é preciso atualizar dois objetos Pedido p = new Pedido(); Item i = new Item(); p.addItem(i); // atualiza dois objetos • Para persistir essa alteração, também é preciso sincronizar os dois objetos em.persist(p); em.persist(i); • O ideal é fazer isto automaticamente: cascade @OneToMany(cascade={CascadeType.PERSIST}, 
 mappedBy="item" )
 private Set<Item> itens = new HashSet<Item>(); – Quando um Pedido for persistido no banco, quaisquer itens que estiverem na sua hierarquia de objetos também serão persistidos
  • 61. CascadeType • O atributo cascade recebe um array {} de opções • Há várias opções para CascadeType. Algumas das mais importantes são – PERSIST – MERGE – REMOVE • Normalmente, usa-se PERSIST com MERGE (inserts e updates feitos automaticamente) @OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE}) • Pode-se usar CascadeType.ALL para que todas as operações sejam transitivas
  • 62. Recuperação de dados: lazy • Se você usar um cliente externo que não mantém aberta a sessão do EntityManager, poderá ter exceções de inicialização lazy (inicialização preguiçosa) quando for acessar objetos dentro de coleções – O query, por default, só retorna a coleção com os ponteiros para os objetos, e eles só podem ser recuperados do banco se houver uma sessão aberta – Como lidar com isto será tratado mais adiante • Uma forma rápida de resolver o problema (por enquanto) é declarar nas associações o atributo fetch=FetchType da forma @OneToMany(mappedBy="pedido", fetch=FetchType.EAGER) private Set<Item> itens = new HashSet<Item>();
  • 63. Outras anotações de associações • @JoinColumn(name="coluna", ...) – Propriedades que não são associações informam a coluna da tabela a qual estão mapeadas com @Column – Associações informam a coluna da associação (foreign key) usando @JoinColumn – Se não informada, o sistema assume que a coluna tem o mesmo nome que o atributo • Consulte a especificação para maiores detalhes sobre as outras anotações e seus atributos
  • 64. 6. Mapeamento de composição • Em ORM, objetos que formam uma composição compartilham a mesma tabela – Em JPA, classes que são componentes são mapeadas como @Embeddable (e não como @Entity) e suas propriedades anotadas como @Embedded na entidade que as contém Cliente nome email cartao Endereco Rua CEP Cidade enderecoEntrega enderecoCobranca nome email cartao ent_rua ent_cep ent_cidade cob_rua cob_cep cob_cidade :Ciente enderecoEntrega:Endereco enderecoCobranca:Endereco <<Entidade>> <<Componente>> @Entity @Embeddable @Embedded
  • 65. Composições (@Embedded) • O objeto embutido (componente) na entidade é a parte dependente da relação de composição – Uma composição ocorre quando uma entidade, que tem identidade na tabela, está composta por objetos que não têm identidade na tabela (seus dados são parte da tabela) – A remoção do registro no banco remove a entidade e seus objetos componentes (não confunda com cascade-delete) • O objeto embutido é propriedade da entidade – Só existem como objetos, mas não como tabelas • Muitas associações 1-1 podem ser implementados como objetos embutidos – Ex: a associação Cliente-CPF mostrada anteriormente
  • 66. Exemplo com @Embedded @Entity @Table(name="CLIENTE") public class Cliente { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Long codigo; private String nome; ... @Embedded private Endereco enderecoCobranca; @Embedded @AttributeOverrides({ @AttributeOverride(name="rua", column=@Column(name="ENT_RUA")), @AttributeOverride(name="cep", column=@Column(name="ENT_CEP")), @AttributeOverride(name="cidade", column=@Column(name="ENT_CIDADE")), }) private Endereco enderecoEntrega; ... @Embeddable public class Endereco { @Column(name="COB_RUA") private String rua; @Column(name="COB_CEP") private String cep; @Column(name="COB_CIDADE") private String cidade; ... } reusa mesma classe Endereco, mas redefine mapeamentos
  • 67. • Herança é o descasamento mais visível entre os mundos relacional e orientado a objetos – Mundo OO possui relacionamento “é um” e “tem um” – Mundo relacional apenas possui relacionamento “tem um” • Há várias estratégias [Ambler 2002]* – Uma tabela por classe concreta: modelo relacional ignora herança e polimorfismo (polimorfismo implícito) – Uma tabela por hierarquia de classes: permite polimorfismo com tabelas não normalizadas mais uma coluna extra contendo informação de tipo – Uma tabela por subclasse: representa relacionamentos “é um” através de relacionamentos “tem um” (chave estrangeira) 7. Mapeamento de herança
  • 68. a. Tabela por classe concreta • Mapeia classes concretas a tabelas @Entity @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) public abstract class Pagamento { @Id @GeneratedValue private long id; } Pagamento id valor Credito numero validade ID VALOR NUMERO VALIDADE 5 <<Entidade>> @Entity Debito banco conta <<Entidade>> @Entity ID VALOR BANCO CONTA 5 CREDITO DEBITO @Entity public class Debito extends Pagamento {...} @Id declarado apenas na superclasse
  • 69. Tabela por classe concreta • Vantagens – Mapeamento direto entre classe e tabela normalizada • Desvantagens – Queries mais complexos e ineficientes • O query polimórfico select p from Pagamento p where p.valor > 1000 gera um SQL (conceitual) com subquery que concatena queries nas tabelas com union: – select ID, VALOR, NUMERO, VALIDADE, BANCO, CONTA from (
 select ID, VALOR, NUMERO, VALIDADE, 
 null as BANCO, null as CONTA from CREDITO 
 union select ID, VALOR, null as NUMERO, null as VALIDADE, 
 BANCO, CONTA from DEBITO 
 ) where VALOR > 1000
  • 70. b. Tabela por hierarquia de classes @Entity @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="TIPO") public abstract class Pagamento { @Id @GeneratedValue private long id; } Pagamento id valor Credito numero validade ID TIPO VALOR NUMERO VALIDADE BANCO CONTA 5 crd 100.0 23459403 12/15 null null 6 deb 100.0 null null 1234-5 993423-3 <<Entidade>> @Entity Debito banco conta <<Entidade>> @Entity PAGAMENTO @Entity @DiscriminatorValue("deb") public class Debito extends Pagamento {...} Coluna (DiscriminatorColumn) presente na tabela mas sem mapeamento na classe
  • 71. b. Tabela por hierarquia de classes • Mapeia-se a hierarquia inteira a uma única tabela – Tabela inclui coluna (não mapeada) para identificar a classe – Há colunas para todas as propriedades de todas as classes • Vantagens – Forma mais eficiente de implementar polimorfismo. – Query polimórfico: select ID, VALOR, BANCO, CONTA, NUMERO, VALIDADE from PAGAMENTO where VALOR > 1000 – Query em classe concreta: select ID, VALOR, BANCO, CONTA, NUMERO, VALIDADE from PAGAMENTO where TIPO = 'deb' and VALOR > 1000 • Desvantagens – Tabelas não normalizadas – Colunas de propriedades declaradas em subclasses precisam aceitar valores nulos (pode ser ruim para grandes hierarquias)
  • 72. c. Tabela por subclasse • Mapeia classes a tabelas @Entity @Inheritance(strategy=InheritanceType.JOINED) public abstract class Pagamento { @Id @GeneratedValue private long id; } Pagamento id valor Credito id numero validade ID NUMERO VALIDADE 9 <<Entidade>> @Entity Debito id banco conta <<Entidade>> @Entity ID BANCO CONTA 5 CREDITO DEBITO @Entity public class Debito extends Pagamento {...} ID VALOR 5 PAGAMENTO ID é PK e FK
  • 73. Uma tabela por subclasse • Herança como relacionamentos de chave estrangeira – Cada subclasse tem sua própria tabela – Cada tabela possui colunas apenas para campos não-herdados, e chave primária que é chave estrangeira da superclasse – Recuperação de dados através de um join das tabelas • Vantagens – Modelo relacional normalizado – Evolução e restrições de integridade simples – Classes/tabelas criadas sem afetar classes/tabelas existentes • Desvantagens – Performance baixa em hierarquias complexas – Difícil de codificar a mão (ruim para integrar com JDBC legado) • Queries – Outer join para pesquisas polimórficas, inner join para queries em classes concretas
  • 74. Qual estratégia usar? • Se não houver necessidade de queries polimórficos ou associações – Tabela por Classe Concreta (TABLE_PER_CLASS) • Se houver necessidade de associações polimórficas, e hierarquia for simples – Tabela por Hierarquia (SINGLE_TABLE) • Se houver necessidade de associações polimórficas mas hierarquia grande (ou não puder usar tabelas não normalizadas) – Tabela por Subclasse (JOINED)
  • 75. 8. Queries JPQL • Toda pesquisa no banco é feita através de Java Persistence Query Language (JPQL) – Linguagem de recuperação de dados similar a outras linguagens de query de objetos (HQL, EJB-QL, etc.) – Parece com SQL, mas é diferente: opera sobre objetos e não tabelas – é mais simples • Queries são objetos da classe Query – Podem ser criados através métodos de EntityManager – Instruções do query podem ser passadas diretamente na criação do query ou declarados em anotações @NamedQuery – Queries podem ser parametrizados • Após sua execução, os dados podem ser recuperados através de métodos da classe Query.
  • 76. API essencial para Queries JPQL • EntityManager – Query createQuery("query jpql"); – Query createNamedQuery("nome de query"); • Query – List<Tipo> getResultList(); – Object getSingleResult(); – Query setParameter(String var, Object obj);
 Query setParameter(int pos, Object obj); – int executeUpdate();
  • 78. Declarações (sintaxe) • SELECT cláusula_select cláusula_from
 [cláusula_where] [cláusula_group_by] [cláusula_having] [cláusula_order_by] • UPDATE cláusula_update • DELETE cláusula_delete

  • 79. Sintaxe elementar SELECT p.nome FROM Produto AS p WHERE p.codigo = '123' Declara variável p como sendo um Produto O que vai ser selecionado Parâmetro SELECT OBJECT (p) 
 FROM Produto p 
 WHERE p.nome = :n AS é opcional Parâmetro do método Objeto (bean) sendo selecionado
  • 80. Palavras-chave JPQL • Usadas na cláusula SELECT – DISTINCT, OBJECT, AVG, MAX, MIN, SUM, COUNT • Usadas na cláusula FROM – IN, AS • Usadas na cláusula WHERE – FROM, WHERE, UPDATE, DELETE, JOIN, OUTER, INNER, LEFT, GROUP, BY, HAVING, FETCH, OBJECT, NULL, TRUE, FALSE, NOT, AND, OR, BETWEEN, LIKE, IN, AS, UNKNOWN, EMPTY, MEMBER, OF, IS, ORDER, BY, ASC, DESC, MOD, UPPER, LOWER, TRIM, POSITION, CHARACTER_LENGTH, CHAR_LENGTH, BIT_LENGTH, CURRENT_TIME, CURRENT_DATE, CURRENT_TIMESTAMP, NEW, EXISTS, ALL, ANY, SOME
  • 81. Cláusula FROM • A cláusula FROM é quem informa o objeto que está sendo pesquisado, e declara variáveis usados no resto do query – Cada variável tem um identificador e um tipo – O identificador é qualquer palavra não-reservada – O tipo é a classe do objeto marcado como @Entity – A palavra-chave AS conecta o tipo ao identificador, mas é opcional FROM Produto AS p Tipo Identificador
  • 82. Cláusula SELECT • A cláusula SELECT informa o que se deseja obter com a pesquisa. Pode retornar – Objetos (interfaces locais ou remotas) – Atributos dos objetos • A palavra SELECT pode ser seguida de DISTINCT para eliminar valores duplicados nos resultados • SELECT utiliza uma variável declarada na cláusula FROM (opcionalmente pode usar OBJECT(p)) • Exemplos SELECT p FROM Produto p SELECT DISTINCT p FROM Produto p SELECT p.codigo FROM Produto p SELECT DISTINCT p.codigo FROM Produto p Retorna objetos Retorna campos
  • 83. Cláusula WHERE • A cláusula WHERE é opcional e restringe os resultados da pesquisa com base em uma ou mais expressões condicionais concatenadas • As expressões podem usar – Literais (strings, booleanos ou números) – Identificadores (declarados no FROM) – Operadores – Funções – Parâmetros do método que utiliza a pesquisa (?1, ? 2, :nome, ...) • Literais – Strings são representados entre apóstrofes: 'nome' – Números têm mesmas regras de literais Java long e double – Booleanos são TRUE e FALSE (case-insensitive)
  • 84. Operadores • Expressões matemáticas – +, -, *, / • Expressões de comparação – =, >, >=, <, <=, <> • Operadores lógicos – NOT, AND, OR • Outros operadores – BETWEEN, NOT BETWEEN – IN, NOT IN – LIKE, NOT LIKE – NULL, NOT NULL – IS EMPTY, IS NOT EMPTY – MEMBER, NOT MEMBER • Operadores do LIKE – _ representa um único caractere – % representa uma seqüência de zero ou mais caracteres – caractere de escape (necessário para usar _ ou %) literalmente
  • 85. Algumas funções • Manipulação de strings (usados em WHERE) – CONCAT, SUBSTRING, TRIM, LOWER, UPPER – LENGTH, LOCATE • Funções aritméticas (usados em WHERE) – ABS, SQRT, MOD, SIZE • Data e hora (usados em WHERE) – CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP • Funções de agregação (usados em SELECT) – COUNT, MAX, MIN, AVG, SUM
  • 86. Exemplos • Encontre todos os produtos que são chips e cuja margem de lucro é positiva – SELECT p 
 FROM Produto p 
 WHERE (p.descricao = 'chip' 
 AND (p.preco - p.custo > 0) • Encontre todos os produtos cujo preço é pelo menos 1000 e no máximo 2000 – SELECT p
 FROM Produto p 
 WHERE p.preco BETWEEN 1000 AND 2000 • Encontre todos os produtos cujo fabricante é Sun ou Intel – SELECT p
 FROM Produto p 
 WHERE p.fabricante IN ('Intel', 'Sun')
  • 87. Exemplos de JPA-QL (2) • Encontre todos os produtos com IDs que começam com 12 e terminam em 3 – SELECT p
 FROM Produto p 
 WHERE p.id LIKE '12%3' • Encontre todos os produtos que têm descrições null – SELECT p
 FROM Produto p 
 WHERE p.descricao IS NULL • Encontre todos os pedidos que não têm itens (coleção) – SELECT pedido FROM Pedido pedido WHERE pedido.itens IS EMPTY • Encontre todos os itens ligados a pedidos em coleção – SELECT item
 FROM Pedido pedido, Item item 
 WHERE item IS MEMBER pedido.itens
  • 88. 9. Queries dinâmicos (JPA 2.0) • Novidade do Java EE 6 – API que permite a construção de queries usando objetos – Inspirado em Criteria do Hibernate e JDO – Pode-se descobrir erros nos queries em tempo de compilação • Queries são mais longos e podem ser mais complexos, mas podem ser alterados dinamicamente • Ideal para formulários de pesquisa onde queries são montados de acordo com preferências do usuário
  • 89. Queries dinâmicos (JPA 2.0) • Pode-se montar o query JPQL • usando queries dinâmicos, da seguinte forma: CriteriaBuilder qb = em.getCriteriaBuilder(); CriteriaQuery<Produto> cq = qb.createQuery(Produto.class); Root<Produto> raiz = cq.from(Produto.class) Predicate condicao = qb.lt(raiz.get(Produto_.preco), 50.0); cq.where(condicao); TypedQuery<Person> query = em.createQuery(cq); List<Produto> resultado = query.getResultList(); select p from Produto p where p.preco < 50.0
  • 90. 10. DAO para JPA em EJB 3 • JPA não precisa de DAO quando usado em EJB 3, que cuida dos contextos transacionais • Mas um DAO ainda é importante – Camada de persistência não precisa ser JPA (pode ser JDBC direto ou usar bancos não relacionais como Redis) – Permite isolar queries (dinâmicos do JPA 2 ou JPQL) • Usando Generics pode-se criar uma interface abstrata reusável
  • 91. DAO abstrato public abstract class AbstractFacade<T> { private Class<T> entityClass; protected abstract EntityManager getEntityManager(); public AbstractFacade(Class<T> entityClass) { this.entityClass = entityClass; } public void create(T entity) { getEntityManager().persist(entity); } public void edit(T entity) { getEntityManager().merge(entity); } public void remove(T entity) { getEntityManager().remove(getEntityManager().merge(entity)); } public T find(Object id) { return getEntityManager().find(entityClass, id); } }
  • 92. DAO concreto • Precisa apenas estender DAO abstrato para cada entidade que se deseja usar – Métodos herdados disponíveis para uso pelos clientes (ex: EJBs) @Stateless public class ProdutoFacade extends AbstractFacade<Produto> { @PersistenceContext(unitName = "LojaVirtual") private EntityManager em; protected EntityManager getEntityManager() { return em; } public ProdutoFacade() { super(Produto.class); } }
  • 93. Referências • Material consultado na elaboração deste capítulo – Oracle. Especificação JPA 2.0: https://jcp.org/aboutJava/ communityprocess/final/jsr317/ e Especificação JPA 1.0 – Apache OpenJPA: https://openjpa.apache.org/ – JBoss.org. Hibernate Entity Manager User Guide http:// docs.jboss.org/hibernate/entitymanager – Christian Bauer e Gavin King. Java Persistence with Hibernate. Manning, 2007 e edições anteriores. – Oracle, Eric Jendrock et al. Java EE 6 Tutorial. http:// docs.oracle.com/javaee/6/tutorial/doc/ e edições anteriores – Versões anteriores deste curso