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

  1. Unidirecional de um para um
  2. Bidirecional de um para um
  3. Unidirecional de um para muitos
  4. Bidirecional de um para muitos
  5. Unidirecional de muitos para um
  6. Unidirecional de muitos para muitos
  7. 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.

Sentido
Figure: Sentido

@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 entidade Pessoa. Uma situação que não seria necessário a persistência explícita da entidade Endereco seria quando na anotação, a propriedade cascade estiver configurada com cascadeType.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étodo public void adicionar( Telefone telefone) e outro public void remover( Telefone telefone), desta forma as demais classes não teriam conhecimento sobre qual estrutura de coleção está sendo utilizada na entidade Pessoa.

@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;
}

results matching ""

    No results matching ""