Relacional

ElementCollection

Explorando a relação entre classes e entidades

Explicação

A notação @ElementCollection do JPA (Java Persistence API) é usada para mapear coleções de tipos básicos ou embutidos (tipos simples como String, Integer, Date, entre outros) ou objetos embutidos (classes anotadas com @Embeddable). Ela é comumente utilizada para armazenar coleções de dados simples em uma tabela separada, mas sem necessidade de criar uma entidade dedicada.

@ElementCollection

Vamos ilustrar isso com o exemplo de um relacionamento entre um Cliente e uma coleção de emails que ele possa ter. A ideia é modelar um cliente que pode ter vários emails, mas sem precisar de uma entidade Email separada.

Exemplo

  1. Definindo a Entidade Cliente

A classe Cliente vai ter uma coleção de emails, que será mapeada usando a anotação @ElementCollection. Para armazenar os emails, o JPA cria uma tabela adicional (de forma implícita) para gerenciar essa coleção.

import javax.persistence.*;
import java.util.Set;

@Entity
public class Cliente {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String nome;

    @ElementCollection
    @Column(name = "email") 
    private Set<String> emails;  // Coleção de emails

    // Lombok ou Getters e Setters
 
}
Oserve que com esta abordagem será criada nova tabela preferencialmente com o nome cliente_email que representará a relação entre um cliente e seus respectivos emails. Consulte a sua base de dados

Explicação das Anotações:

  1. @Entity: Marca a classe como uma entidade JPA, ou seja, ela será mapeada para uma tabela no banco de dados.
  2. @Id e @GeneratedValue: Indicam que o campo id é a chave primária da entidade e que o valor será gerado automaticamente.
  3. @ElementCollection: Indica que o campo emails é uma coleção de elementos simples (neste caso, String). O JPA vai tratar isso de forma especial, criando uma tabela para armazenar esses valores de forma associada à entidade Cliente.
  4. @Column: Especifica o nome da coluna (email) na tabela de coleção.

Estrutura da Tabela no Banco de Dados

Com essa estrutura, o JPA vai gerar as seguintes tabelas:

  1. Cliente
  • id (PK)
  • nome
  1. cliente_email
  • cliente_id (FK para Cliente)
  • email

Por exemplo, a tabela cliente_email pode ter os seguintes registros:

cliente_idemail
1cliente1@email.com
1cliente2@email.com
2cliente3@email.com
2cliente4@email.com

A tabela Cliente pode ter registros como:

idnome
1João
2Maria

Consultando os Dados

Se você tiver um objeto Cliente no seu código, você pode acessar a lista de emails diretamente:

Cliente cliente = //seu repository ou entitymanager
Set<String> emails = cliente.getEmails();
for (String email : emails) {
    System.out.println(email);
}

Vantagens do @ElementCollection:

  • Não há necessidade de criar uma entidade separada para representar os emails.
  • A tabela associada é criada automaticamente.
  • O JPA lida com a persistência da coleção de maneira eficiente.

Limitações:

  • Não é possível fazer operações complexas com essas coleções (como fazer consultas diretamente na tabela de emails). Elas são basicamente uma estrutura simples de dados.
  • Não há suporte para relacionamentos mais complexos (como ManyToMany ou OneToMany), pois o foco do @ElementCollection é trabalhar com coleções simples.

CollectionTable

A anotação @CollectionTable em JPA é utilizada em conjunto com @ElementCollection para mapear coleções de elementos embutidos ou coleções de tipos básicos em uma tabela separada no banco de dados.

Estrutura da Anotação

@CollectionTable(
    name = "nome_da_tabela",
    joinColumns = @JoinColumn(name = "coluna_de_chave_estrangeira")
)

Exemplo Prático

Imagine a nossa entidade Cliente agora precisar identificar que na sua lista de e-mails os mesmos tenham um ou mais atributos como por exemplo, tipo podendo PESSOAL ou CORPORATIVO.

Para utilizar este tipo de mapeamento, será necessário a inclusão da anotação @Embeddable que é explorada em nosso tema Anotações Avançadas Incorporadas.
import jakarta.persistence.*;

@Embeddable
public class Email {
    //SEM NECESSIDADE DE ID
    //@Id
    //private Integer id;
    private String destinatario;
    private String tipo;
    
     // Lombok ou Getters e Setters
    
}

Conclusão

A anotação @ElementCollection do JPA é uma maneira conveniente de mapear coleções simples de dados como strings (no caso dos emails) sem a necessidade de criar uma entidade extra. Isso torna a estrutura de dados mais limpa e fácil de trabalhar quando o relacionamento entre as entidades não exige um modelo mais complexo.