Relacionamento
- As entidades se relacionam com outras entidades...
O mapeamento pode variar de acordo com o papel, a direção do relacionamento (Sentido):Unidirecional ou Bidirecional, e a cardinalidade do relacionamento: um para um; um para muitos \/ muitos para um; muitos para muitos.
Quanto aos papéis temos três perspectivas diferentes:
- Visão de um lado do relacionamento.
- Visão do outro lado do relacionamento.
Visão de uma perspectiva global.
A cardinalidade refere-se a quantidade de entidades que estão envolvidas no relaciomaneto: um ou muitos. Mas podem ser opcionais: Ordinalidade ou Opcionalidade.
Quanto ao sentido, podemos definir de uma forma global dois tipos de dependências:
- Unidirecional.
- Bidirecional.
Mapeamento de relacionamentos
- Unidirecional de um para um
- Bidirecional de um para um
- Unidirecional de um para muitos
- Bidirecional de um para muitos
- Unidirecional de muitos para um
- Unidirecional de muitos para muitos
- Bidirecional de muitos para muitos
O mapeamento é feito de acordo com as seguintes anotações:
Relacionamento | Anotação | |
---|---|---|
Um pra um | @OneToOne |
|
Muitos pra um | @ManyToOne |
|
Um pra muitos | @OneToMany |
|
Muitos pra muitos | @ManyToMany |
Unidirecional
Nos relacionamentos unidirecionais, mapeamos somente uma das entidades envolvidas no relacionamento. Nestes relacionamentos, temos os conceitos de entidade fonte e alvo. Há mapeamento apenas a entidade fonte.

@OneToOne
Define a coluna na tabela Pessoa
que faz referência a chave primária de Endereco
.
@Entity
public class Pessoa {
private Endereco endereco;
@OneToOne(cascade={cascadeType.ALL})
@JoinColumn(name=“ENDERECO_ID”)
public Endereco getEndereco(){
return endereco;
}
}
// Não há qualquer mapeamento na entidade Endereco
@Entity
public class Endereco{
private String rua;
private String estado;
}
Neste exemplo, será criada uma chave estrangeira na tabela Pessoa
para representar o relacionamento com a entidade Endereco
.
Nota:
Devido a dependência entre as entidades, a entidade
Endereco
deverá ser persistida antes da entidadePessoa
. Uma situação que não seria necessário a persistência explícita da entidadeEndereco
seria quando na anotação, a propriedadecascade
estiver configurada comcascadeType.ALL
.
@OneToMany
Dado que a entidade Pessoa
possui uma coleção de Telefone
. Teremos na tabela Telefone
uma coluna que faz referência a chave primária da entidade Pessoa
. Este mapeamento segue a mesma regra definida no mapeamento do banco de dado relacional.
@Entity
public class Pessoa {
@OneToMany(cascade={CascadeType.ALL})
private Set<Telefone> phones = new HashSet<>();
}
@Entity
public class Telefone {
private String numero;
private String tipo;
}
A coleção utilizada na entidade Pessoa
poderia ser definida por qualquer classe do tipo Collection
, List
ou Set
.
Precisamos ter atencão quando realizamos as operação que manipulam objetos de coleções. Na operação de remoção, observamos que é preciso remover a instância de Telefone
da coleção de Pessoa
, antes de remover a instência de Telefone
.
Telefone telefone = em.find(Telefone.class, 2);
Pessoa pessoa = em.find(Pessoa.class, 1);
pessoa.getTelefones().remove(telefone);
em.remove(telefone);
em.flush();
Na operação de inserção, observamos que é preciso remover a instância de Telefone
da coleção de Pessoa
, antes de remover a instência de Telefone
.
Pessoa pessoa = new Pessoa();
Set<Telefone> telefones = new HashSet<>();
Telefone t1 = new Telefone(“99999999”);
Telefone t2 = new Telefone(“35314560”);
telefones.add(t1);
telefones.add(t2);
pessoa.setPhones(telefones);
em.persist(pessoa);
Nota:
idealmente para cada operação de manipulação dessas coleções, há um método na entidade
Pessoa
para abstrair qual estrutura está sendo utilizada. Por exemplo, teríamos um métodopublic void adicionar( Telefone telefone)
e outropublic void remover( Telefone telefone)
, desta forma as demais classes não teriam conhecimento sobre qual estrutura de coleção está sendo utilizada na entidadePessoa
.
@ManyToOne
Dado que a entidade Pessoa
possui uma referência a qual Faculdade
esteja frequentando. Teremos na tabela Pessoa
uma coluna que faz referência a chave primária da entidade Faculdade
. Este mapeamento segue a mesma regra definida no mapeamento do banco de dado relacional.
@Entity
public class Pessoa {
@ManyToOne(cascade={CascadeType.ALL})
private Faculdade faculdade;
}
// Não há qualquer mapeamento na entidade Faculdade
@Entity
public class Faculdade {
private String nome;
private Endereco endereco;
}
@ManyToMany
Dado que a entidade Pessoa
possui uma coleção de Hobby
e que um mesmo Hobby
pode pertencer a diversas pessoas. Este mapeamento segue a mesma regra definida no mapeamento do banco de dado relacional. Desta forma, será criada uma tabela que contém as chaves primárias de ambas as entidades.
@Entity
public class Pessoa {
@ManyToMany(cascade={CascadeType.ALL})
private Collection<Hobby> hobbies = new ArrayList<>();
}
// Não há qualquer mapeamento na entidade Hobby
@Entity
public class Hobby {
private int id;
private String nome;
}