Buscar

Mapeamento Objeto Relacional JPA

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 39 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 39 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 39 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

CENTRO UNIVERSITÁRIO DE PATOS DE MINAS 
DISCIPLINA: DESENVOLVIMENTO WEB II 
EDUARDO HENRIQUE SILVA 
 
 
 
 
 
 
 
 
 
MAPEAMENTO OBJETO RELACIONAL COM JPA 
SUMÁRIO 
1 INTRODUÇÃO ......................................................................................... 1 
1.1 O QUE É PERSISTÊNCIA ............................................................................................ 1 
1.2 PERSISTÊNCIA NO PARADIGMA ORIENTADO A OBJETO ................................ 1 
2 MAPEAMENTO OBJETO RELACIONAL (ORM) ............................ 1 
2.1 POR QUE USAR O ORM? ............................................................................................ 2 
2.2 CAMADA DE PERSISTÊNCIA ................................................................................... 2 
2.3 JAVA PERSISTENCE API (JPA) ................................................................................. 2 
3 MAPEANDO ENTIDADES ..................................................................... 3 
3.1 POJO ............................................................................................................................... 3 
3.2 CRIANDO DE ENTIDADES ........................................................................................ 4 
3.2.1 Anotações @Entity e @Table ......................................................................................... 5 
3.2.2 Anotações @Id e @GeneratedValue .............................................................................. 6 
3.2.3 Anotações @Column e @Basic ...................................................................................... 7 
3.2.4 Anotação @Temporal ..................................................................................................... 9 
3.2.5 Anotação @Transient ................................................................................................... 10 
3.2.6 Mapeando a tabela Automóvel ..................................................................................... 11 
4 MAPEANDO ASSOCIAÇÕES ............................................................. 12 
4.1 RELACIONAMENTO UM PARA UM @ONETOONE ............................................. 12 
4.1.1 Anotação @OneToOne ................................................................................................. 13 
4.1.2 Anotações @PrimaryKeyJoinColumn e @JoinColumn ............................................... 14 
4.1.3 Mapeando a classe pessoa ............................................................................................ 15 
4.1.4 Cascade ......................................................................................................................... 16 
4.2 MAPEANDO COM O USO DA HERANÇA .............................................................. 17 
4.3 RELACIONAMENTO UM PARA MUITOS @ONETOMANY E @MANYTOONE . 19 
4.3.1 Anotação @ManyToOne .............................................................................................. 20 
4.3.2 Anotação @ManyToOne .............................................................................................. 20 
4.4 RELACIONAMENTO MUITOS PARA MUITOS @MANYTOMANY ...................... 21 
5 OUTRAS ANOTAÇÕES ........................................................................ 24 
5.1 CHAVE PRIMÁRIA COMPOSTA ............................................................................. 24 
5.2 ANOTAÇÃO @NAMEDQUERY ................................................................................. 25 
6 UNIDADE DE PERSISTÊNCIA ........................................................... 26 
7 GERENCIANDO OBJETOS PERSISTENTES .................................. 27 
7.1 ENTITY MANAGER ...................................................................................................... 27 
7.1.1 Entity Manager gerenciado pelo contêiner ................................................................... 28 
7.1.2 Entity Manager gerenciado pela aplicação ................................................................... 29 
7.1.3 Contexto de persistência ............................................................................................... 29 
8 JAVA PERSISTENCE QUERY LANGUAGE ....................................... 30 
8.1 CRIANDO CONSULTAS ............................................................................................ 31 
8.2 ESTRUTURA BÁSICA ............................................................................................... 32 
8.2.1 Where ............................................................................................................................ 33 
8.2.2 Outras consultas ............................................................................................................ 33 
8.3 MÉTODOS PARA CRIAR CONSULTAS .................................................................. 33 
8.3.1 Named Queries ............................................................................................................. 34 
8.3.2 Dynamic Queries .......................................................................................................... 35 
8.3.3 Invocando uma consulta ............................................................................................... 35 
8.3.4 Passagem de parâmetros ............................................................................................... 36 
REFERÊNCIAS ................................................................................................ 36 
 
 
1 
1 INTRODUÇÃO 
1.1 O QUE É PERSISTÊNCIA 
Persistência é um dos conceitos fundamentais no desenvolvimento de aplicações. 
Se um software não preservar os dados quando ele for desligado, o software será de pouco uso 
prático. Quando falamos de persistência, normalmente estamos falando sobre como guardar 
dados em um banco de dados. 
1.2 PERSISTÊNCIA NO PARADIGMA ORIENTADO A OBJETO 
Em uma aplicação orientada a objetos, a persistência permite guardar o estado 
(valores dos atributos) de um objeto em disco. Em uma aplicação Java podemos ter objetos 
persistentes e objetos transientes, um objeto transiente possui a vida limitada determinada 
pelo processo que o instanciou. 
Na persistência, geralmente utilizamos um banco de dados relacional, que possui 
interfaces de programação baseadas em SQL. Banco de dados relacional é orientação a 
objetos são representações totalmente diferentes. Em um banco de dados relacional temos 
tabelas, registros, e colunas, na OO temos classes, objetos, atributos e métodos. O desafio é 
fazer os nossos objetos serem persistidos em um banco de dados relacional. 
2 MAPEAMENTO OBJETO RELACIONAL (ORM) 
O mapeamento objeto relacional (ORM) permite que os nossos objetos sejam 
persistidos em um banco de dados relacional. Podemos mapear entidades (classes) para 
tabelas e atributos para colunas utilizando metadados que descrevem o mapeamento entre 
eles. 
O ORM trabalha com a transformação dos dados de uma representação para outra, 
permitindo a persistência automatizada e transparente dos objetos em uma aplicação Java para 
as tabelas de um banco de dados relacional. 
 
2 
2.1 POR QUE USAR O ORM? 
 Produtividade: O ORM elimina muitas tarefas rotineiras do trabalho e deixa 
você se concentrar no problema do negócio. Por exemplo: Não é necessário 
escrever comandos de inserção e alteração em SQL para cada tabela do banco 
de dados; 
 Manutenibilidade: O ORM reduz substancialmente as linhas de código, e 
permite o isolamento das representações orientado a objetos e banco de dados 
relacional; 
 Desempenho: O desempenho de um software com a persistência implementada 
a mão (sem utilização do ORM), pode ser mais rápida, quando uma 
persistência ORM. Em contraparte, o ORM permite otimizaçõese ainda 
melhora a produtividade dos desenvolvedores; 
 Independência: O ORM abstrai a sua aplicação da interação direta com o banco 
de dados SQL, permitindo a portabilidade, ou seja, nossa aplicação poderá 
mudar de fornecedor de banco de dados sem precisar ser reestruturada. 
 
2.2 CAMADA DE PERSISTÊNCIA 
A camada de persistência é o grupo de classes e componentes responsáveis por 
guardar os dados e recupera-los em um ou vários repositórios de dados. Essa camada 
necessariamente inclui o modelo das entidades de domínio de negócio. 
2.3 JAVA PERSISTENCE API (JPA) 
Java Persistence API é uma especificação ORM do JEE que trata exclusivamente 
da persistência, entidades, metadados, mapeamento objeto relacional, interfaces para 
gerenciar a persistência, e a linguagem de consulta. Através do JPA podemos mapear através 
de anotações as entidades para tabelas e atributos para colunas, além persistir e recuperar 
objetos. 
 
3 
3 MAPEANDO ENTIDADES 
3.1 POJO 
Plain Old Java Objects (POJOs – o bom e velho objeto puro Java) é uma 
abordagem “de volta às raízes” que essencialmente ressuscita o JavaBeans, um modelo de 
componente para desenvolvimento de UI, e a reaplica-los na camada de negócios. A maioria 
dos desenvolvedores usa agora o termo POJO e JavaBeans quase como sinônimos. 
Um POJO declara métodos de negócios, que definem o comportamento, e 
propriedades, que representam o estado. Algumas propriedades representam associações para 
outros POJOs. 
No modelo de persistência do JPA, uma entidade é um POJO. O código abaixo 
mostra uma classe POJO, implementando a entidade Cor. 
 
public class Cor implements Serializable { ← Implementação do Serializable 
 
 private static final long serialVersionUID = 1L; 
 private Short idCor; ← Atributos encapsulados 
 private String descricao; 
 
 public Cor(){← Construtor da classe sem argumentos 
 } 
 
 public Short getIdCor() {← Métodos de acesso aos atributos 
 return idCor; 
 } 
 
 public void setIdCor(Short idCor) { 
 this.idCor = idCor; 
 } 
 
 public String getDescricao() { 
 return descricao; 
 } 
 
 public void setDescricao(String descricao) { 
 this.descricao = descricao; 
 } 
 
} 
Então um POJO deve ter apenas atributos encapsulados e métodos de acesso, bem 
como, um construtor sem argumentos. 
A interface Serializable é opcional, embora ele seja obrigatório quando for 
necessário transmitir o objeto através de uma interface remota (RMI) ou armazena-lo em uma 
4 
sessão do navegador de internet. Através dela podemos transformar um objeto em uma cadeia 
de caracteres e vice-versa. 
3.2 CRIANDO DE ENTIDADES 
Agora iremos criar as nossas entidades baseado no diagrama de entidade e 
relacionamento apresentado na apostila “Desenvolvimento Java EE”. Na apostila 
“Desenvolvimento Java EE” foi apresentado como criar o projeto no NetBeans, dando 
sequência iremos criar nossas entidades no projeto “br.com.aula.javaweb-ejb”, pois, ele 
contém todas as regras de negócios do software. 
Clique com o botão direito em cima do projeto selecione o menu “Novo/Pacote 
Java”. Crie um pacote com o nome “br.com.aula.javaweb.entity”. Nossas classes de entidades 
serão criadas nesse pacote. Inicialmente, será apresentado como mapear as classes, 
posteriormente iremos realizar o mapeamento das associações. 
Iremos realizar o mapeamento objeto relacional na tabela “Marca”. 
 
 
No mapeamento objeto relacional, uma tabela será uma classe, e as colunas serão 
atributos da classe. E cada registro na tabela será um objeto. O código abaixo é referente ao 
 
public class Marca implements Serializable { 
 
 private static final long serialVersionUID = 1L; 
 
 private Short idMarca; 
 
 private String descricao; 
 
 //Métodos get/set 
} 
 
Veja que cada coluna no banco de dados possui um tipo, e na classe também 
devemos informar o tipo do atributo, porém, os tipos em um banco de dados relacional nem 
sempre são iguais os tipos na orientação a objetos, por exemplo, “Varchar” e “String”, não há 
o tipo “Varchar” em Java, porém ambos são tipos inerentes. Na orientação a objetos 
5 
geralmente possui tipos inerentes ao banco de dados relacional. A tabela abaixo apresenta os 
tipos em Java referentes os tipos SQL. 
 
Tipo inerente ao padrão SQL Tipo Java 
INTERGER int ou java.lang.Integer 
BIGINT long ou java.lang.Long 
SMALLINT short ou java.lang.Short 
FLOAT float ou java.lang.Float 
DOUBLE double ou java.lang.Double 
NUMERIC java.math.BigDecimal 
CHAR(1) java.lang.String 
VARCHAR java.lang.String 
TINYINT byte ou java.lang.Byte 
BIT boolean ou java.lang.Boolean 
DATE java.util.Date 
TIME java.util.Date 
VARBINARY byte[] 
BLOB java.sql.Blob 
 
Em Java podemos definir os tipos dos atributos usando tipos primitivos como 
“int” ou tipo Wrapper como “java.lang.Integer”. Os Wrappers são representações dos tipos 
primitivos em forma de objetos. Os Wrappers possuem métodos de conversão de dados, e 
podem receber o valor nulo, enquanto, um tipo primitivo não pode recever valor nulo. 
3.2.1 Anotações @Entity e @Table 
Para mapear uma classe com o JPA utilizaremos as anotações (annotations) 
representadas pelo sinal “@”, elas estão presentes no pacote “javax.persistence”. Vamos 
começar pela classe “Marca”. 
 
@Entity 
@Table(name = "marca") 
public class Marca implements Serializable { 
 
 private static final long serialVersionUID = 1L; 
 
} 
A anotação “@Entity” permite ao provedor de persistência reconhece a classe 
como uma classe persistente e não como um simples POJO. 
A anotação “@Table” é opcional, ela diz para qual tabela do banco de dados a 
classe está mapeada, através do atributo “name”. Se essa anotação não for especificada então, 
6 
o JPA assume que a tabela possui o mesmo nome da classe. Se a tabela e a classe tiverem 
nomes diferentes então é necessário utilizar essa anotação. 
O banco de dados padrão é definido no arquivo de configuração do JPA. Podemos 
especificar entidades para tabelas de banco de dados diferentes do definido no arquivo de 
configuração “@Table(name = "marca",schema = "javaweb")”, utilizando o atributo 
“schema” para especificar qual o banco de dados da tabela. 
3.2.2 Anotações @Id e @GeneratedValue 
Em um banco de dados relacional, a chave primária identifica cada registro na 
tabela. A chave primária deve ser única e não permite valores nulos. A tabela “Marca” a 
chave primária é representada pela coluna “idMarca” auto incremental, vamos então mapeá-
la. 
@Entity 
@Table(name = "marca") 
public class Marca implements Serializable { 
 
 private static final long serialVersionUID = 1L; 
 
 @Id 
 @GeneratedValue(strategy=GenerationType.IDENTITY) 
 @Column(name = "idMarca",nullable = false) 
 private Short idMarca; 
 
 //Métodos get/set 
} 
 
A anotação “@Id” é utilizado para dizer que o atributo é uma chave primária, 
sendo um identificar exclusivo para o conjunto de dados. 
A anotação “@GeneratedValue”, é utilizada para denotar que o valor do atributo 
“idMarca” o seu valor será gerado automaticamente pela aplicação ou pelo provedor de 
persistência. 
Essa anotação pode possuir quatro estratégias: 
 
 IDENTITY especifica que o provedor de persistência deve gerar o valor da 
do atributo usando a coluna de identidade do banco de dados 
“@GeneratedValue(strategy=GenerationType.IDENTITY)”; 
7 
 TABLE especifica que o provedor de persistência deve gerar o valor do 
atributo usando uma tabela do banco de dados para garantir a 
exclusividade “@GeneratedValue(strategy=GenerationType.TABLE)”; 
 SEQUENCEespecifica que o provedor de persistência deve gerar o valor 
do atributo usando uma coluna de sequência de dados 
“@GeneratedValue(strategy=GenerationType. SEQUENCE)”; 
 AUTO especifica que o provedor de persistência deve escolher a estratégia 
adequada para gerar o valor do atributo 
“@GeneratedValue(strategy=GenerationType.AUTO)” ou 
“@GeneratedValue”; 
3.2.3 Anotações @Column e @Basic 
A anotação “@Column” é opcional, ela permite mapear a coluna da tabela com o 
atributo. Se a coluna da tabela tiver o mesmo nome do atributo, essa anotação é opcional. 
Nessa anotação temos os seguintes atributos: 
 
 name (String): indica o nome da coluna da tabela que o atributo está 
mapeando; 
 unique (boolean): indica se a coluna da tabela é único (padrão “false”); 
 nullable (boolean): indica se a coluna poderá receber valores nulos 
(padrão “true”); 
 lenght (int): indica a capacidade máxima de caracteres (usado apenas para 
atributos que armazenam cadeias de caracteres como String) (padrão 
“255”); 
 insertable (boolean): indica se na inserção do objeto, o atributo também 
deve ser inserido (padrão “true”); 
 updatable (boolean): indica se na alteração do objeto, o atributo também 
deve ser alterado (padrão “true”);. 
 
Essa anotação não é obrigatória, se seus atributos estão bem mapeados, você pode 
realizar uma engenharia reversa e gerar banco de dados de acordo com os mapeamentos, caso 
necessário. 
8 
Agora iremos mapear as colunas não chaves, na tabela “Marca”, temos apenas a 
coluna “descricao”. 
@Entity 
@Table(name = "marca") 
public class Marca implements Serializable { 
 
 private static final long serialVersionUID = 1L; 
 
 @Id 
 @GeneratedValue(strategy=GenerationType.IDENTITY) 
 @Column(name = "idMarca",nullable = false) 
 private Short idMarca; 
 
 
 @Column(name = "descricao",nullable = false,length = 50) 
 private String descricao; 
 
 //Métodos get/set 
} 
 
Para mapear a coluna “descricao” utilizou apenas a anotação “@Column”, que 
não é obrigatório. Foi utilizado o atributo “length”, que diz ao provedor de persistência que o 
atributo pode ter até 50 caracteres. 
A anotação “@Basic” é opcional, utilizada para mapear uma coluna do tipo 
numérico ou texto. Ela possui dois atributos: 
 fetch (FetchType): diz para o provedor de persistência em tempo de 
execução se o dado deve ser carregado preguiçosamente 
(“FetchType.LAZY” a aplicação diz se ela quer que o dado seja carregado) 
ou ansiosamente (“FetchType.EAGER” toda vez que a entidade é buscada 
o dado também é carregado) (padrão “EAGER”); 
 opcional (boolean): diz para o provedor de persistência se o valor pode ser 
nulo (mesma função do “nullable” da anotação “@Column”) (padrão 
“true”);. 
 
Veja um exemplo de uma anotação “@Basic”. 
 
@Basic(fetch = FetchType.LAZY,optional = false) 
@Column(name = "descricao",nullable = false,length = 50) 
private String descricao; 
Essa anotação é usada geralmente quando você não quer que o atributo seja 
carregado automaticamente ao realizar uma busca. Nesse projeto não utilizaremos a anotação 
“@Basic”. 
9 
Pronto, a entidade está mapeada. Veja o código final. 
 
@Entity 
@Table(name = "marca") 
public class Marca implements Serializable { 
 
 private static final long serialVersionUID = 1L; 
 @Id 
 @GeneratedValue(strategy=GenerationType.IDENTITY) 
 @Column(name = "idMarca",nullable = false) 
 private Short idMarca; 
 
 
 @Column(name = "descricao",nullable = false,length = 50) 
 private String descricao; 
 
 //Métodos get/set 
 
 
} 
3.2.4 Anotação @Temporal 
Em Java, podemos usar o “java.util.Date” ou “java.Util.Calendar” para 
armazenar datas e suas várias representações, como, data, hora, minutos ou milissegundos. 
Para especificar isso no mapeamento objeto relacional podemos usar a anotação 
“@Temporal”. Essa anotação possui três possibilidades de valor: 
 
 DATE: utilizado para representar apenas datas (dia, mês e ano); 
 TIME: utilizando para representar apenas tempo (horas, minutos, segundos 
e milissegundos); 
 TIMESTAMP: utilizado para representar data e horas (dias, mês, ano, 
horas, segundos, e milissegundos). 
 
A tabela “Pessoa” possui um campo do tipo “Date”, vamos realizar o 
mapeamento dessa tabela. 
 
 
10 
@Entity 
@Table(name = "pessoa") 
public class Pessoa implements Serializable { 
 
 private static final long serialVersionUID = 1L; 
 
 @Id 
 @GeneratedValue(strategy=GenerationType.IDENTITY) 
 @Column(name = "idPessoa",nullable = false) 
 private Integer idPessoa; 
 
 @Column(name = "nome",nullable = false,length = 100) 
 private String nome; 
 
 @Column(name = "cpf",nullable = false,length = 14) 
 private String cpf; 
 
 @Column(name = "dataNascimento",nullable = false) 
 @Temporal(TemporalType.DATE) 
 private Date dataNascimento; 
 
 //Métodos get/set 
 
} 
 
Como a data de nascimento de uma pessoa não possui, horas e nem minutos, essa 
coluna foi mapeada com o tipo “Date”. Toda coluna que representar uma data ou tempo 
deve ter a anotação “@Temporal”. 
3.2.5 Anotação @Transient 
Com o JPA, a classe que é anotada com o “@Entity”, todos os atributos são 
automaticamente mapeados para a tabela. Se não for necessário mapear um atributo, você 
pode usar o “@Transient”. Por exemplo, anteriormente mapeamos a tabela “Pessoa”, essa 
tabela possui o atributo data de nascimento. Poderíamos adicionar ainda o atributo idade, que 
seria calculado a partir da data de nascimento, porém esse atributo não seria persistido no 
banco de dados, ele seria um atributo transiente. Veja o exemplo. 
 
@Entity 
@Table(name = "pessoa") 
public class Pessoa implements Serializable { 
 
 private static final long serialVersionUID = 1L; 
 
 @Id 
 @GeneratedValue(strategy=GenerationType.IDENTITY) 
 @Column(name = "idPessoa",nullable = false) 
 private Integer idPessoa; 
11 
 
 @Column(name = "nome",nullable = false,length = 100) 
 private String nome; 
 
 @Column(name = "cpf",nullable = false,length = 14) 
 private String cpf; 
 
 @Column(name = "dataNascimento",nullable = false) 
 @Temporal(TemporalType.DATE) 
 private Date dataNascimento; 
 
 @Transient 
 private Integer idade; 
 
 //Métodos get/set 
 
 //Método para calcular a idade; 
} 
3.2.6 Mapeando a tabela Automóvel 
Já estudamos as anotações básicas para mapear uma entidade, como mais um 
exemplo, segue o código do mapeamento da tabela Automóvel. 
 
@Entity 
@Table(name = "automovel") 
public class Automovel implements Serializable { 
 
 private static final long serialVersionUID = 1L; 
 
 @Id 
 @GeneratedValue(strategy=GenerationType.IDENTITY) 
 @Column(name = "idAutomovel",nullable = false) 
 private Integer idAutomovel; 
 
 @Column(name = "ano",nullable = false) 
 private Integer ano; 
 @Column(name = "valor",nullable = true) 
 private Double valor; 
 
 @Column(name = "quantidadePortas",nullable = false) 
 private Short quantidadePortas; 
 
 //Métodos get/set 
 
} 
Observe-se que na coluna “valor”, o atributo “nullable” do mapeamento 
“@Column” está como “true”. Pois nesse campo, de acordo com o banco de dados, pode 
receber valores nulos. 
Bom, agora você é capaz de mapear todas as tabelas no banco de dados. 
12 
4 MAPEANDO ASSOCIAÇÕES 
Em um projeto orientado a objetos está repleto de classes e associações entre as 
classes. Essas associações são estruturas que ligam objetos de um tipo para objetos de outro 
tipo, permitindo um objeto delegarfuncionalidades a outros objetos. Vários tipos de 
associações podem existir entre as classes. 
Em um banco de dados relacional podemos ter diversas relações entre tabelas. No 
banco de dados relacional, um relacionamento é indicado pela chave estrangeira, na 
orientação a objetos uma associação é indicada por uma referência de uma classe. Com as 
anotações do JPA poderemos mapear essas associações de acordo com o modelo relacional. 
4.1 RELACIONAMENTO UM PARA UM @ONETOONE 
No diagrama de entidade e relacionamento possuímos dois relacionamentos um 
para um. 
 
Um relacionamento um para um de “Pessoa” para “Funcionário” e outro 
relacionamento de um para um de “Pessoa” para “Usuário”. 
Na programação orientada a objetos, podemos adotar que a classe “Funcionário” é 
uma subclasse de “Pessoa”, pois, uma pessoa é um funcionário. Então no relacionamento de 
“Pessoa” para “Funcionário” adotaremos outra estratégia de mapeamento, utilizando o 
conceito de herança. 
Primeiramente, mapearemos o relacionamento de um para um com “Pessoa” e 
“Usuário”. 
 
@Entity 
@Table(name = "usuario") 
public class Usuario implements Serializable { 
13 
 
 private static final long serialVersionUID = 1L; 
 
 @Id 
 @Column(name = "idPessoa",nullable = false,updatable = false,insertable = 
false) 
 private Integer idPessoa; 
 
 @Column(name = "login",nullable = false,length = 45) 
 private String login; 
 
 @Column(name = "senha",nullable = false,length = 150) 
 private String senha; 
 
 @OneToOne(fetch = FetchType.LAZY) 
 @JoinColumn(name = "idPessoa",nullable=false) 
 private Pessoa pessoa; 
 
 //Métodos get/set 
} 
Quando dizemos que um usuário pode ser de apenas uma pessoa, estamos dizendo 
que um objeto usuário pode ter apenas uma referência do objeto pessoa. A referência 
“private Pessoa pessoa;”, indica que o objeto usuário é de apenas uma pessoa. 
4.1.1 Anotação @OneToOne 
A anotação “@OneToOne”, indica para o provedor de persistência que um 
relacionamento entre as entidades é de um para um. Nessa associação temos um atributo 
denominado “fetch”, com a mesma característica do “fetch” presente na anotação “@Basic”. 
O valor padrão é “EAGER” 
 
 FetchType.LAZY diz para o provedor de persistência que a referência deve 
ser carregada preguiçosamente, ou seja, a referência é buscada apenas se a 
aplicação solicitar; 
 FetchType.EAGER diz para o provedor de persistência que a referência 
deve ser carregada ansiosamente, ou seja, toda vez que a entidade for 
buscada a referência também deve ser buscada. 
 
Geralmente, mapeamos as associações com o “LAZY”, pois, imagine um busca 
por um objeto que possui várias associações, e nessa busca todas as associações são 
carregadas, sendo que nem sempre utilizaremos todas as associações. Isso pode gerar um 
14 
problema de desempenho em determinadas funções. Com o “LAZY”, a aplicação que vai 
definir quando e quais associações serão carregadas. 
4.1.2 Anotações @PrimaryKeyJoinColumn e @JoinColumn 
Também utilizamos a anotação “@PrimaryKeyJoinColumn”, para mapear a chave 
estrangeira presente na tabela que estamos mapeando. Utilizamos dois atributos: 
 
 name: utilizado para informar o nome da coluna referente a chave estrangeira 
que define a associação da tabela; 
 referencedColumnName: utilizado para informar o nome da coluna chave 
primária da tabela relacionada, que virá para a tabela mapeada como chave 
estrangeira. Se a chave primária da tabela relacionada tiver o mesmo nome da 
chave estrangeira, essa anotação não é obrigatória. 
 
Quando a chave estrangeira também for uma chave primária utilizamos o 
“@PrimaryKeyJoinColumn”, porém quando a chave for apenas estrangeira utilizamos o 
“@JoinColumn”. O “@JoinColumn” possui alguns atributos adicionais: 
 
 unique (boolean): indica se a chave estrangeira da tabela é único (padrão 
“false”); 
 nullable (boolean): indica se a chave estrangeira poderá receber valores 
nulos (padrão “true”); 
 insertable (boolean): indica se na inserção do objeto, a chave estrangeira 
também deve ser inserido (padrão “true”); 
 updatable (boolean): indica se na alteração do objeto, a chave estrangeira 
também deve ser alterado (padrão “true”);. 
 
Quando uma tabela possui mais de uma chave estrangeira vindo de uma outra 
tabelas, utilizamos as anotações “@PrimaryKeyJoinColumns(value={})” e 
“@JoinColumns(value={})”. Onde podemos passar através do atributo “value” uma coleção 
de “@JoinColumn” ou “@PrimaryKeyJoinColumn”. 
Veja um exemplo: 
15 
 
@JoinColumns(value = { 
@JoinColumn(name = "idTeste1",nullable = false), 
@JoinColumn(name = "idTeste2",nullable = false)}) 
private Combustivel combustivel; 
 
4.1.3 Mapeando a classe pessoa 
No exemplo anterior mapeamos o relacionamento de usuário para funcionário. 
Iremos realizar o mapeamento bidirecional, então será necessário realizar o mapeamento de 
funcionário para o usuário. 
@Entity 
@Table(name = "pessoa") 
public class Pessoa implements Serializable { 
 
 private static final long serialVersionUID = 1L; 
 
 @Id 
 @GeneratedValue(strategy = GenerationType.IDENTITY) 
 @Column(name = "idPessoa",nullable = false) 
 private Integer idPessoa; 
 
 @Column(name = "nome",nullable = false,length = 100) 
 private String nome; 
 
 @Column(name = "cpf",nullable = false,length = 14) 
 private String cpf; 
 
 @Column(name = "dataNascimento",nullable = false) 
 @Temporal(TemporalType.DATE) 
 private Date dataNascimento; 
 
 
 @OneToOne(fetch = FetchType.LAZY,mappedBy = "pessoa",cascade = 
CascadeType.ALL) 
 private Usuario usuario; 
 
 //Métodos get/set 
} 
Na tabela “Pessoa” não há chave estrangeria referente a tabela “Usuário” então 
não precisamos do “@JoinColumn”. Porém, precisamos do atributo “mappedBy”. O 
“mappedBy” identifica o atributo que possui o mapeamento da associação, ele é necessário 
para relacionamentos bidirecionais. Veja: 
 
@Entity 
@Table(name = "pessoa") 
public class Pessoa{ 
 
16 
 //Outos atributos 
 
 @OneToOne(fetch = FetchType.LAZY, 
 mappedBy = "pessoa", 
 cascade = CascadeType.ALL) 
 private Usuario usuario; 
 
 //Métodos get/set 
} 
@Entity 
@Table(name = "usuario") 
public class Usuario { 
 
 //Outros atributos 
 
 @OneToOne(fetch = FetchType.LAZY) 
 @JoinColumn(name = "idPessoa",) 
 private Pessoa pessoa; 
 
 //Métodos get/set 
 
} 
O valor do “mappedBy” deve ser o nome da referência que possui o mapeamento. 
4.1.4 Cascade 
Na classe “Pessoa” utilizou um atributo denominado “cascade” no mapeamento 
do relacionamento com a classe “Usuário”. Esse atributo permite realizar ações em cascata, 
ou seja, as operações efetuadas nos objetos serão propagadas para as os atributos que estão 
mapeados com o “cascade”. Ele pode ser utilizado em qualquer mapeamento de associações. 
O JPA fornece quatro valores possíveis para o “cascade”. 
 
 ALL: equivale as operações de MERGE, PERSIST, REFRESH e REMOVE; 
 MERGE: se o estado do objeto for transferido para o banco de dados, 
então a associação também será transferida; 
 PERSIST: se o objeto for persistido, então a associação também será 
persistida; 
 REFRESH: se o objeto for atualizado a partir do banco de dados, então a 
associação também será atualizada; 
 REMOVE: se objeto for removido, então a associação também será 
removida. 
 
17 
No exemplo da classe “Pessoa” utilizamos o “Cascade.ALL” para a associação 
“usuário”. Isso diz, que quando eu salvar, excluir, alterar um objeto do tipo pessoa, também 
será salvado, excluído ou alteradoo objeto usuário, sem a necessidade de algum código 
adicional. 
4.2 MAPEANDO COM O USO DA HERANÇA 
Herança é um conceito completamente desconhecido e não implementado em 
banco de dados relacional. O JPA permite mapear tabelas do banco de dados relacional para 
uma associação de herança da orientação a objeto. 
No projeto, temos as classes “Pessoa” e “Funcionário” que podem ser 
respectivamente, superclasse e subclasse, e no banco de dados formam um relacionamento um 
para um. 
 
 
 
Primeiramente vamos mapear a superclasse “Pessoa”. 
 
@Entity 
@Table(name = "pessoa") 
@Inheritance(strategy = InheritanceType.JOINED) 
@DiscriminatorColumn(name = "tipo",discriminatorType = DiscriminatorType.CHAR) 
public class Pessoa implements Serializable { 
 
 //Atributos e mapeamentos 
 
 //Métodos get/set 
} 
A anotação “@DiscriminatorColumn” é utilizada para identificar a coluna da 
entidade “Pessoa” que irá armazenar qual o tipo de entidade que o registro está associado. 
18 
Exemplo: Se um registro na tabela “Pessoa” possui o valor “F” na coluna “tipo”, então esse 
registro está associado a um registro na tabela “Funcionário”. 
Na superclasse a única mudança é o mapeamento “@Inheritance” que define qual 
estratégia adotada no banco de dados relacional. Considere o diagrama de classe abaixo para 
entender as três estratégias de mapeamento do JPA: 
 
 
 JOINED: cada entidade na hierarquia é mapeada com seus atributos; 
 
 SINGLE_TABLE: todos os atributos das classes na hierarquia serão colocados e 
uma única tabela; 
 
 TABLE_PER_CLASS: cada entidade concreta na hierarquia possui sua própria 
tabela. 
 
 
Na maioria das vezes usamos a estratégia “JOINED”, devido ao uso das formas 
normais ao desenvolver o modelo de entidade e relacionamento. 
O próximo passo é mapear a subclasse “Funcionário”. 
 
19 
 
@Entity 
@Table(name = "funcionario") 
@PrimaryKeyJoinColumn(name ="idPessoa") 
@DiscriminatorValue("F") 
public class Funcionario extends Pessoa{ 
 
 @Column(name = "salario",nullable = false) 
 @NotNull(message = "Informe o salário") 
 private Double salario; 
 
 //Métodos get/set 
} 
 
Observe-se que não possuímos um atributo que mapeia a chave estrangeira, pois 
iremos reusar todos os atributos na classe “Pessoa”. Nesse mapeamento não se esqueça de 
usar a declaração “extends”. A anotação “@DiscriminatorValue” irá dizer qual valor será 
inserido no campo “@Discriminator” na entidade pai. 
 Na subclasse, devemos apenas mapear qual a coluna chave primária. Não 
necessário criar um atributo para essa coluna. Para mapear a chave primaria usamos a 
anotação “@PrimaryKeyJoinColumn” já vista anteriormente em um relacionamento um para 
um. Essa anotação deve ser realizada na classe. No atributo “name” será passado o nome da 
chave primária e estrangeira da tabela “Funcionário” e na “referecedColumnName” o nome 
da chave primária que veio da tabela "Pessoa". 
4.3 RELACIONAMENTO UM PARA MUITOS @ONETOMANY E 
@MANYTOONE 
No diagrama de entidade e relacionamento do projeto, possui vários 
relacionamentos de um para muitos entre as tabelas. Como exemplo, mapearemos o 
relacionamento de um para muitos entre “Marca” e “Modelo”. 
 
 
 
 
20 
4.3.1 Anotação @ManyToOne 
Nesse relacionamento podemos dizer que uma marca possui zero ou vários 
modelos, e um modelo é de apenas uma marca. 
Primeiramente, será mapeada a tabela que possui a chave estrangeira referente ao 
relacionamento de um para muitos, nesse caso a tabela “Modelo”. 
 
@Entity 
@Table(name = "modelo") 
public class Modelo implements Serializable { 
 private static final long serialVersionUID = 1L; 
 @Id 
 @GeneratedValue(strategy=GenerationType.IDENTITY) 
 @Column(name = "idModelo",nullable = false) 
 private Short idModelo; 
 
 @Column(name = "descricao",nullable = false,length = 50) 
 private String descricao; 
 
 @ManyToOne(fetch = FetchType.LAZY) 
 @JoinColumn(name = "idMarca",nullable = false) 
 private Marca marca; 
 
 //Métodos get/set 
} 
 
Conforme apresentado anteriormente, um Modelo é de apenas uma Marca, então 
na classe “Modelo” terá uma referência da classe “Marca”. 
A anotação “@ManyToOne” indica um relacionamento onde um modelo poder ter 
apenas uma marca (e uma marca pode ter vários modelos). Essa anotação permite os atributos 
“fetch” e “cascade” já apresentados anteriormente. 
A anotação “@JoinColumn” indica o mapeamento da chave estrangeira, essa 
anotação também já foi apresentada anteriormente. 
4.3.2 Anotação @ManyToOne 
Agora, será realizado o mapeamento bidirecional, nesse caso a tabela “Marca”. 
Onde dissemos que uma marca pode ter zero ou vários modelos. 
@Entity 
@Table(name = "marca",schema = "javaweb") 
public class Marca implements Serializable { 
 
 private static final long serialVersionUID = 1L; 
21 
 
 @Id 
 @GeneratedValue(strategy = GenerationType.IDENTITY) 
 @Column(name = "idMarca",nullable = false) 
 private Short idMarca; 
 
 @Basic(fetch = FetchType.EAGER,optional = false) 
 @Column(name = "descricao",nullable = false,length = 50) 
 private String descricao; 
 
 @OneToMany(fetch = FetchType.LAZY,mappedBy = "marca") 
 private List<Modelo> modelos; 
 
 //Métodos get/set 
} 
 
Como dito, uma marca pode ter vários modelos. Um objeto “Marca” deve possuir 
uma coleção de objetos do tipo “Modelo”, para declarar uma coleção podemos utilizar as 
interfaces “List” ou “Set”. Nessa associação utilizou a anotação “@OneToMany” indicando 
que é uma relacionamento um para muitos. Essa anotação permite os atributos “fetch”, 
“cascade” e o “mappedBy” para indicar qual referência está mapeado o relacionamento. 
Pronto, agora você pode realizar os mapeamentos de um para muitos de 
“Automóvel” para “Cor”, “Automóvel” para “Combustível”, “Automóvel” para “Modelo” e 
“Automóvel” para “AutomovelFoto”. 
4.4 RELACIONAMENTO MUITOS PARA MUITOS @MANYTOMANY 
No diagrama de entidade e relacionamento possuímos um relacionamento de 
muitos para muitos entre as tabelas “Automóvel” e “Opcional” criando a tabela do meio 
denominada “AutomovelOpcional”. 
 
 
 
22 
No mapeamento objeto relacional não é necessário a criação da classe que mapeia 
a tabela do meio. Teremos uma associação entre as classes de muitos para muitos. Um objeto 
“Automóvel” possui uma coleção de objetos do tipo “Opcional” e vice versa. 
 
 
 
No mapeamento de muitos para muitos, podemos escolher uma classe para 
mapear a tabela do meio. Nesse exemplo, vamos mapear a tabela do meio na classe 
“Automóvel”. 
@Entity 
@Table(name = "automovel") 
public class Automovel implements Serializable { 
 
 private static final long serialVersionUID = 1L; 
 
 @Id 
 @GeneratedValue(strategy=GenerationType.IDENTITY) 
 @Column(name = "idAutomovel",nullable = false) 
 private Integer idAutomovel; 
 
 @Column(name = "ano",nullable = false) 
 private Integer ano; 
 
 @Column(name = "valor",nullable = true) 
 private Double valor; 
 
 @Column(name = "quantidadePortas",nullable = false) 
 private Short quantidadePortas; 
 
 @ManyToMany(fetch = FetchType.LAZY) 
 @JoinTable(name = "AutomovelOpcional", 
 joinColumns = @JoinColumn(name = "idAutomovel"), 
 inverseJoinColumns = @JoinColumn(name = "idOpcional")) 
 private List<Opcional> opcionais; 
 
 //Métodos get/set 
 
} 
 
A anotação “@ManyToMany” indica um relacionamento de muitos para muitos, 
ela pode conter os atributos “fetch”, “cascade” e “mappedBy” (usado para criar o 
mapeamento bidirecional) apresentados anteriormente.A anotação “@JoinTable” é utilizada para mapear uma tabela que se relaciona 
com a tabela que está sendo mapeada. O atributo “name” identifica o nome da tabela, nesse 
23 
exemplo, a tabela do meio “AutomovelOpcional” será mapeada na associação, não sendo 
necessário uma classe. 
O atributo “joinColumns” recebe uma coleção de “@JoinColumn” referentes as 
chaves estrangeiras e primárias da tabela do meio que também são chaves primárias na classe 
que está mapeada a anotação “@JoinTable”. 
O atributo “inverseJoinColumns” recebe uma coleção de “@JoinColumn” 
referentes as chaves estrangerias e primárias da tabela do meio que também são chaves 
primárias da classe referenciada (classe inversa). 
Para realizar o mapeamento bidirecional, iremos mapear uma coleção de 
automóveis na classe “Opcional”, não será necessário o uso do “@JoinTable”. 
 
@Entity 
@Table(name = "opcional") 
public class Opcional implements Serializable { 
 
 private static final long serialVersionUID = 1L; 
 
 @Id 
 @GeneratedValue(strategy=GenerationType.IDENTITY) 
 @Column(name = "idOpcional",nullable = false) 
 private Short idOpcional; 
 
 @Column(name = "descricao",nullable = false,length = 50) 
 private String descricao; 
 
 @ManyToMany(fetch = FetchType.LAZY,mappedBy = "opcionais") 
 private List<Automovel> automoveis; 
 
 //Métodos get/set/ 
 
} 
 
A anotação “@ManyToMany” indica um relacionamento de muitos para muitos, 
ela pode conter os atributos “fetch”, “cascade” e “mappedBy” O “mappedBy” está dizendo 
para o provedor de persistência que a associação foi mapeada na classe “Automóvel” (pois a 
anotação “@ManyToMany” está anotada para uma coleção do tipo “Automóvel”).na 
referência denominada “opcionais”. 
Agora, todas as classes do projeto podem ser mapeadas, pois, foi visto anotações 
de classes, atributos e associações. 
 
 
24 
5 OUTRAS ANOTAÇÕES 
Serão apresentadas algumas anotações que podem ser úteis durante esse projeto, 
ou até mesmo em outro projeto com requisitos diferentes. 
 
5.1 CHAVE PRIMÁRIA COMPOSTA 
Em um modelo de banco de dados relacional podemos ter tabelas com mais de 
uma chave primária (chave primária composta). 
 
 
 
No JPA, definimos uma classe para conter os atributos referente a chave 
composta. 
 
@Embeddable 
public class TurmaId implements Serializable { 
 
 private static final long serialVersionUID = 1L; 
 
 @Column(name = "periodoLetivo",nullable = false,length = 10) 
 private String periodoLetivo; 
 
 @Column(name = "codigoTurma",nullable = false,length = 45) 
 private String codigoTurma; 
 
 //Métodos get/set 
} 
 
A anotação “@Embeddable” é utilizada para dizer que essa classe será 
incorporada a outra entidade. 
 
@Entity 
@Table(name = "turma") 
public class Turma implements Serializable { 
25 
 
 private static final long serialVersionUID = 1L; 
 
 @EmbeddedId 
 private TurmaId id; 
 
 @Column(name = "sala",nullable = false,length = 45) 
 private String sala; 
 
 //Métodos get/set 
} 
 
A anotação “@EmbeddedId” diz ao provedor de persistência que os atributos 
contidos referência anotada compõe a chave primária da entidade. 
Se existe uma coluna na chave primária composta que também é chave estrangeira 
(PFK), como o código da turma. Na associação é necessário colocar o mapeamento 
“@MapsId”. 
 
@MapsId("codigoTurma") 
@ManyToOne 
@JoinColumn(name=" codigoTurma") 
private Turma turma; 
5.2 ANOTAÇÃO @NAMEDQUERY 
E anotação “@NamedQuery” permite definir consultas estáticas em JPQL (Java 
Pesistence Query Language). JPQL é usado para definir consultas em unidades persistentes 
independente do mecanismo de banco de dados. 
 
@Entity 
@Table(name = "cor") 
@NamedQuery(name = "todos",query = "select c from Cor c") 
public class Cor implements Serializable { 
 
} 
 
Nesse exemplo definimos uma consulta chamada “todos” que permite consultar 
todas as instâncias persistentes de “Cor”. 
O exemplo abaixo apresenta como referência a consulta definida pela 
“@NamedQuery”. Posteriormente, iremos aprender como realizar um CRUD (Create, Read, 
Update e Delete). 
26 
 
List<Cor> cores = em.createNamedQuery("todos", Cor.class).getResultList(); 
 
Podemos, definir várias consultas nomeadas através da anotação 
“@NamedQueries”. 
 
@Entity 
@Table(name = "cor") 
@NamedQueries({ 
 @NamedQuery(name = "todos", query = "select c from Cor c"), 
 @NamedQuery(name = "por_id", query = "select c from Cor c where c.idCor = 
:idCor")}) 
public class Cor implements Serializable { 
} 
 
Lembrando que você não pode ter consultas com nomes iguais no seu contexto de 
persistência. Na apostila gerenciamento dos objetos persistentes, será apresentado um pouco 
mais do JPQL. 
 
6 UNIDADE DE PERSISTÊNCIA 
A unidade de persistência é utilizada para configurar informações sobre o 
provedor de persistência (JPA), tal como, identificar as classes que serão mapeadas como 
entidades e configurações de banco de dados. Para criar a unidade de persistência no Eclipse 
clique um arquivo XML denominado “persistence.xml” dentro da pasta “WEB-INF”. O 
conteúdo desse arquivo pode ser visto no quadro a seguir. 
<?xml version="1.0" encoding="UTF-8"?> 
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"> 
 <persistence-unit name="br.unipam.locadora" transaction-type="JTA"> 
 <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
 <jta-data-source>locadora</jta-data-source> 
 <class>br.unipam.locadora.entity.Modelo</class> 
 <class>br.unipam.locadora.entity.Cliente</class> 
 <properties> 
 <property name="eclipselink.logging.level" value="FINE"/> 
 <property name="eclipselink.logging.parameters" value="true"/> 
 </properties> 
 </persistence-unit> 
</persistence> 
 
27 
No provedor de persistência “<provider>” podemos informar qual API irá 
fornecer uma implementação para o JPA. Iremos utilizar o EclipseLink da Eclipse Foundation 
como provedor de persistência. O JPA possui outras implementações, tais como, Hibernate da 
JBoss, TopLink da Oracle. Fica a sua escolha de qual implementação utilizar. 
Algumas configurações podem ser vistas no quadro a seguir: 
 
Configuração Descrição 
<provider> Define o provedor de persistência que 
implementa o JPA 
<class> Define as classes que estão mapeadas como 
entidades. 
<jta-data-source> É o nome do ponto de acesso para o banco de 
dados. 
eclipselink.logging.parameters 
eclipselink.logging.level 
Habilita os logs do provedor de persistência, 
útil para analisar os comandos SQL gerados 
pelo provedor. 
 
Após a criação da unidade de persistência será necessário criar o “jta-data-
source”. Assim dentro da pasta “WEB-INF” clique um arquivo denominado “resources.xml”. 
Esse arquivo irá possuir informações para a conexão com o banco de dados. O valor fornecido 
o id do recurso “id="locadora"” deverá ser informa no arquivo de persistência através da tag 
“<jta-data-source>” 
 
<?xml version="1.0"?> 
<resources> 
 <Resource id="locadora" type="javax.sql.DataSource"> 
 jdbcDriver = com.mysql.jdbc.Driver 
 jdbcUrl = jdbc:mysql://localhost:3306/locadora 
 password = fepam 
 userName = root 
 </Resource> 
</resources> 
 
7 GERENCIANDO OBJETOS PERSISTENTES 
7.1 ENTITY MANAGER 
O Entity Manager é uma peça importante do JPA. Ele gerencia o estado e o ciclo 
de vida das entidades, bem como, consultas de entidades dentro do contexto de persistência. O 
28 
Entity Manager é responsável por criar, remover e atualizar instâncias de entidades 
persistentes e consultarentidades pela chave primária ou por consultas customizadas. A 
Tabela a seguir apresenta alguns métodos do Entity Manager. 
 
Método Descrição 
void persist(Object object) Permite adicionar uma instância ao contexto 
de persistência. 
void merge(Object object) Permite alterar o estado de um objeto no 
contexto de persistência. 
void remove(Object object) Permite excluir uma instância do contexto de 
persistência. 
 
O Entity Manager é uma interface implementada pelo provedor de persistência 
que irá gerar e executar comandos SQL. 
Para obter a implementação dessa interface, existe duas formas: 
 
 Gerenciado pelo contêiner: o contêiner (Servlet, EJB, WebServices, entre 
outros) é responsável por obter uma instância do Entity Manager e 
gerenciar o seu ciclo de vida (controlar transações e abrir e fechar o Entity 
Manager, por exemplo).; 
 Gerenciado pela aplicação: sua aplicação é responsável por obter uma 
instância do Entity Manager e gerenciar o seu ciclo de vida (controlar 
transações e abrir e fechar o Entity Manager, por exemplo). 
 
7.1.1 Entity Manager gerenciado pelo contêiner 
A anotação “@PersistenceContext” diz para o contêiner que ele deve injetar uma 
instância do provedor de persistência na referência Entity Manager e ele será responsável por 
gerenciar o ciclo de vida do Entity Manager. Essa anotação pode receber o atributo 
“unitName” para especificar o nome da unidade de persistência do “persistence.xml”. 
No arquivo “persistence.xml” devemos definir o atributo “transaction-
type="JTA"”. 
29 
 
@PersistenceContext 
private EntityManager em; 
 
Quando o “EntityManager” é gerenciado pelo contêiner não precisamos preocupar 
com iniciar e fechar uma transação. Pois, o contêiner realiza essa tarefa para nós. 
 
public void save(Marca marca) { 
 em.persist(marca); 
} 
 
7.1.2 Entity Manager gerenciado pela aplicação 
Em um Entity Manager gerenciado pela aplicação usaremos uma fábrica para 
criar uma instância da implementação do Entity Manager. 
 
private EntityManager em 
 = Persistence 
 .createEntityManagerFactory("br.com.aula.javaweb-ejbPU") 
 .createEntityManager(); 
 
Para criar uma instância do Entity Manager devemos passar o nome da unidade de 
persistência. Agora ao iniciar uma transação, a aplicação é responsável por gerenciar o 
contexto de persistência. 
 
public void salvar (Marca marca){ 
em.getTransaction().begin(); 
em.persist(marca); 
em.getTransaction().commit(); 
} 
 
 
7.1.3 Contexto de persistência 
O contexto de persistência é um conjunto de instâncias de entidades persistentes 
de um dado momento para uma transação do usuário. No contexto de persistência não existem 
instâncias duplicadas, ou seja, se no contexto tiver uma instância de “Marca” com o 
30 
identificador igual “1”, não há nenhuma outra instância de “Marca” com identificador igual a 
“1” no contexto de persistência. 
Ao invocar o método “persist” do Entity Manager estamos adicionando uma 
instância ao contexto de persistência, caso ela não exista. Ao realizar uma consulta pela chave 
primária, Entity Manager verifica primeiramente se a instância não está no contexto de 
persistência. Assim, o contexto de persistência armazena todos os objetos persistentes, e ao 
fim da transação ele efetua as alterações necessárias no banco de dados. Os objetos apenas 
vivem no contexto de persistência durante a transação. 
A Figura 2 apresenta o ciclo de vida do contexto de persistência. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Figura 1 - Ciclo de vida do contexto de persistência 
 
8 JAVA PERSISTENCE QUERY LANGUAGE 
O Java Persistence Query Language (JPQL) é usado para definir consultas de 
entidades persistentes independente do banco de dados utilizado. A sintaxe do JPQL segue o 
Inicia uma transação 
de consultar saldo 
Contexto de persistência 
Objeto 1 Objeto 2 
Objeto 3 Objeto 4 
Servidor Web (Web Contêiner) 
Inicializa o contexto 
de persistência 
<Passo 1> 
<Passo 2> 
Descarrega os 
objetos persistentes 
<Passo 3> 
<Passo 4> 
Finaliza a transação 
31 
padrão do SQL (linguagem utilizada em banco de dados relacionais), a diferença é que o 
resultado SQL é obtido na forma de registros e colunas e o JPQL retorna uma instância ou um 
conjunto de instâncias. 
A sintaxe do JPQL é orientada a objetos, encapsulando a estrutura de consultas do 
banco de dados. Os desenvolvedores precisam saber a estrutura de classes de entidades e não 
a estrutura de tabelas. 
 
 
 
 
 
 
 
 
Figura 2 - Entendendo a conversão JPQL para SQL 
 
8.1 CRIANDO CONSULTAS 
Através das classes apresentadas pela Figura 4, iremos realizar algumas consultas em JPQL. 
 
 
 
Figura 3 - Classes para criação de consultas JPQL 
 
 
A Tabela 2 apresenta algumas consultas com JPQL. Todos os nomes utilizados 
para montagem da consulta são referentes aos nomes das classes e atributos e não o nome das 
tabelas e colunas do seu banco de dados. 
 
Entity 
Manager 
Comando JPQL: 
select c from MinhaClasse as c 
Comando SQL: 
select * from MinhaTabela as c 
Registros da tabela 
“MinhaTabela” 
Objetos do tipo 
“MinhaClasse” 
32 
Consulta Descrição 
Select c from Marca c Seleciona as instâncias persistentes de 
Marca. Essa consulta pode retornar uma 
instância ou uma coleção de Marcas 
Select c.descricao from Marca c Seleciona uma String ou uma coleção de 
Strings referente à descrição dos objetos 
Marca. 
Select c from Marca c 
 where c.descricao = ‘Fiat’ 
Seleciona as instâncias persistentes de Marca 
que possui a descrição igual a “Fiat”. 
Select distinct c.descricao from Marca c Seleciona uma String ou uma coleção de 
Strings não repetidas, referentes à descrição 
dos objetos Marca. 
Select count(c) from Marca c Retorna a quantidade de instâncias 
persistentes de Marca. 
Select c from Marca c 
 join fetch c.modelos m 
Retorna as marcas que estão associadas com 
o atributo “modelos”. A instrução “fetch” diz 
para carregar os objetos persistentes no 
atributo. 
Select m from Modelo m 
 join fetch m.marca c 
 where c.descricao = :descricao 
Retorna todos os Modelos que possuem a 
uma instância de marca com a descrição 
repassada. O “:descricao” indica um 
parâmetro será repassado em tempo de 
execução. 
Tabela 1 - Consultas JPQL 
8.2 ESTRUTURA BÁSICA 
Em uma consulta JPQL segue a seguinte estrutura: 
 
SELECT < expressão > 
FROM < expressão > 
[WHERE < expressão >] 
[ORDER BY < expressão >] 
33 
[GROUP BY < expressão >] 
[HAVING < expressão >] 
8.2.1 Where 
A cláusula where pode possuir os seguintes operadores de comparação: =, >, >=, 
<, <=, <>, [NOT] BETWEEN, [NOT] LIKE, [NOT] IN, IS [NOT] NULL, IS [NOT] EMPTY. 
8.2.2 Outras consultas 
A Oracle disponibiliza em seu site toda a estrutura para construção de consultas 
em JPQL, acesso o site 
http://docs.oracle.com/cd/E17904_01/apirefs.1111/e13946/ejb3_langref.html para obter mais 
dicas sobre a linguagem JPQL. 
8.3 MÉTODOS PARA CRIAR CONSULTAS 
O JPA 2.0 oferece quatro tipos de criação de consultas, com propósitos diferentes: 
 Dynamic queries: consiste em uma consulta JPQL dinamicamente 
especificada em tempo de execução; 
 Named queries: são consultas estáticas e imutáveis, definidas pela 
anotação “@NamedQuery”; 
 Native queries: consiste em uma consulta utilizando a linguagem SQL 
nativa; 
 Criteria API: é um novo conceito de criação de consultas através de uma 
API orientada a objetos. 
 
A interface Entity Managerfornece vários métodos para a criação de consultas. 
Esses métodos retornam uma interface Query ou TypedQuery. A interface Query é utilizadas 
quando o tipo do resultado é Object, e TypedQuery é usando quando o tipo do resultado é 
determinado por você. 
34 
Nessa apostila, veremos apenas criação de consultas com JPQL, então veremos 
apenas criação de Dynamic queries e Named queries. 
8.3.1 Named Queries 
Através da anotação “@NamedQuery” podemos definir consultas estáticas dentro 
das nossas classes de entidades. 
 
@Entity 
@Table(name = "marca",schema = "javaweb") 
@NamedQueries({@NamedQuery(name = "marca.findAll", 
query = "select m from Marca m")}) 
public class Marca implements Serializable { 
 
} 
 
Uma Named query uma vez criada, não é possível altera-la em tempo de 
execução. Mas é possível criar uma Named query parametrizada. 
 
@Entity 
@Table(name = "marca",schema = "javaweb") 
@NamedQueries({@NamedQuery(name = "marca.findById", 
query = "select m from Marca m where m.idMarca = :idMarca")}) 
public class Marca implements Serializable { 
 
} 
 
Através de uma instância do Entity Manager (“em”), podemos criar uma consulta 
a partir de uma Named query invocando o método “createNamedQuery”: 
 
TypedQuery<Marca> marcaQuery = 
 em.createNamedQuery("marca.findAll", Marca.class); 
 
Uma TypedQuery ao ser executada irá retornar instâncias do tipo “Marca”. 
Podemos também definir uma Query, que irá retornar instâncias do tipo “Object”, sendo 
necessário realizar um cast (conversão) para o tipo “Marca”. 
 
 Query Query = 
 em.createNamedQuery("marca.findAll"); 
35 
8.3.2 Dynamic Queries 
As Dynamic queries podem ser criadas dinamicamente em tempo de execução, 
invocando o método “createQuery” de uma instância do Entity Manager. 
 
TypedQuery<Cor> corQuery = 
 em.createQuery("select c from Cor c", Cor.class); 
8.3.3 Invocando uma consulta 
Ao definir uma consulta, iremos dizer ao Entity Manager para ele trazer as 
instâncias de acordo com a consulta. O JPA fornece dois métodos: 
 
 getSingleResult(): retorna apenas uma instância; 
 getResultList(): retorna uma coleção de instâncias. 
 
Esses métodos são invocados a partir de uma instância de Query ou TypedQuery. 
Veja um exemplo do “getResultList” em um objeto TypedQuery. 
 
TypedQuery<Cor> corQuery = 
 em.createQuery("select c from Cor c", Cor.class); 
 
List<Cor> cores = corQuery.getResultList(); 
 
Veja um exemplo do “getSingleResult” em um objeto TypedQuery. 
 
TypedQuery<Cor> corQuery = 
 em.createQuery("select c from Cor c where c.idCor = 1", Cor.class); 
 
Cor cor = corQuery.getSingleResult(); 
Conforme dito anteriormente o objeto Query é utilizado quando é necessário 
retornar uma instância do tipo Object. 
 
Query corQuery = 
 em.createQuery("select c from Cor c where c.idCor = 1"); 
 
Object object = corQuery.getSingleResult(); 
36 
8.3.4 Passagem de parâmetros 
Em Named queries e Dynamic queries podemos passar parâmetros em tempo de 
execução. Para criar um parâmetro em uma consulta utilizamos os “:” (dois pontos) seguido 
do nome do parâmetro. Através do método “setParameter(nome,valor)” inserimos o 
parâmetro em nossa consulta. 
 
TypedQuery<Cor> corQuery = 
em.createQuery("select c from Cor c where c.idCor = :idCor", Cor.class); 
 
corQuery.setParameter("idCor", 1); 
 
Cor cor = corQuery.getSingleResult(); 
 
REFERÊNCIAS 
 BAUER, Christian, KING, Gavin. Java Persistence com Hibernate. Rio de Janeiro: Ciência 
Moderna, 2007. 
 GONCALVES, Antonio. Beginning Java™ EE 6 Platform with GlassFish™ 3. 2. ed. New 
York: Apress, 2010. 
ORACLE. The Java EE 6 Tutorial. Disponível em: 
<http://docs.oracle.com/javaee/6/tutorial/doc/>. Acesso em: 20 jan. 2014.

Outros materiais