Lista de coleções

Bem, você viu como mapear tipos simples. Agora é hora de passar para questões mais interessantes - como mapear coleções de objetos.

E podemos ter objetos em 5 grupos:

  • Array - uma matriz de objetos
  • Lista - lista de objetos
  • Conjunto - conjunto de objetos
  • Mapa - um dicionário de objetos
  • Coleção - uma coleção de objetos

E um exemplo de uma classe com um campo de coleção:

@Entity
@Table(name="user")
class User {
   @Id
   @Column(name="id")
   public Integer id;

   @magical-annotation
   public List messages;
}

Então, o que é essa anotação mágica que nos permitirá armazenar não um campo, mas muitos valores?

Essa anotação é chamada @ElementCollection . Exemplo:

@Entity
@Table(name="user")
class User  {
   @Id
   @Column(name="id")
   public Integer id;

   @ElementCollection
   public List<String> messages;
}

Está escrito de maneira muito simples, mas funciona de maneira não trivial.

mesa auxiliar

Todos os campos da classe Entity que contêm muitos elementos e são marcados com a anotação @ElementCollection estão contidos no banco de dados em uma tabela auxiliar especial. O que, de fato, é lógico.

Esta tabela pode conter dados em duas formas:

  • Ordered (List, Map) contém três colunas:
    • Coluna Chave (Chave Estrangeira) – referência ao ID do objeto pai.
    • Coluna de índice - posição/índice na coleção.
    • Coluna do elemento - valor.
  • Unordered (Set) contém duas colunas:
    • Coluna Chave (Chave Estrangeira) – referência ao ID do objeto pai.
    • Coluna do elemento - valor.

Você também pode definir o nome dessa tabela explicitamente usando uma anotação:

@CollectionTable(name="table_name")

Exemplo:

@Entity
@Table(name="user")
class User {
   @Id
   @Column(name="id")
   public Integer id;

   @ElementCollection
   @CollectionTable(name="user_message")
   public List<String> messages;
}

Importante! Se a anotação @CollectionTable não for especificada, o Hibernate criará o próprio nome da tabela com base no nome da classe e no nome do campo: a classe User e o campomensagensnomeie a tabela "User_messages".

coleção coleção

Mas não vamos deixar a criação da tabela auxiliar para o Hibernate e criá-la nós mesmos. Primeiro precisamos criar uma tabela com duas colunas:

CREATE TABLE user_message {
    user_id INT,
    message VARCHAR(255)
};

Observe que esta tabela não possui sua própria coluna de id. Esta é a principal característica das mesas auxiliares. Você se familiarizará com outros tipos de tabelas auxiliares um pouco mais tarde.

Agora precisamos mapear esta tabela para o nosso campomensagensna classe Usuário . Isso ficará assim:

@Entity
@Table(name="user")
class User {
   @Id
   @Column(name="id")
   public Integer id;

   @ElementCollection
   @CollectionTable(name="user_message", joinColumns = @JoinColumn(name = "user_id"))
   @Column(name = "message")
   public Set<String> messages;
}

Aqui vale a pena prestar atenção a duas coisas.

Primeiro, a coluna da mensagem, especificada com a anotação @Column(name = "message") , está na tabela auxiliar user_message, não na tabela user.

Em segundo lugar, na anotação @JoinColumn(name = "user_id") , especificamos o nome da coluna user_id, que se refere ao id da tabela user. Isso é para que o Hibernate saiba como combiná-los corretamente.

Coleção

Se você deseja armazenar os elementos ordenados de uma lista ou array em uma tabela auxiliar, você precisa de uma tabela com três colunas:

CREATE TABLE user_message {
    user_id INT,
    index INT,
    message VARCHAR(255)
};

Se você não gostar do nome da coluna "index" ou não puder alterá-lo, poderá especificar um nome diferente durante o mapeamento. Para fazer isso, você precisa usar a anotação @Index .

Exemplo:

@Entity
@Table(name="user")
class User {
   @Id
   @Column(name="id")
   public Integer id;

   @ElementCollection
   @CollectionTable(name="user_message",
       	indexes = { @Index(columnList = "list_index") }
       	joinColumns = @JoinColumn(name = "user_id"))
   @Column(name = "message")
   public List<String> messages;
}

Coleção de mapas

E, finalmente, você deseja armazenar não apenas uma coleção, mas um HashMap e precisa de duas colunas em uma tabela auxiliar para isso:

CREATE TABLE user_message {
    user_id INT,
    key VARCHAR(255),
    message VARCHAR(255)
};

Para especificar uma chave para um Mapa, você precisa da anotação @MapKeyColumn .

Exemplo:

@Entity
@Table(name="user")
class User {
   @Id
   @Column(name="id")
   public Integer id;

   @ElementCollection
   @CollectionTable(name="user_message", joinColumns = @JoinColumn(name = "user_id"))
   @MapKeyColumn(name = "key")
   @Column(name = "message")
   public Map<String, String> messages;
}

Você pode encontrar mais informações na documentação oficial .