No momento de fazer o mapeamento objeto relacional, temos a opção de definir como vamos tratar as chaves primárias: se vamos trazer para a aplicação a responsabilidade de definir esse valor único (quando declaramos apenas a anotação @Id), ou se vamos deixar essa responsabilidade com o provedor de persistência (quando também declaramos a anotação @GeneratedValue).

Ao citar o termo provedor de persistência, saiba que estamos referenciando o framework escolhido para que a aplicação possa se comunicar com o banco de dados. Alguns exemplos são o Hibernate, EclipseLink e OpenJPA.

Neste documento será apresentado como utilizar a anotação @GeneratedValue.

@GeneratedValue

A anotação @GeneratedValue é utilizada para informar que a geração do valor do identificador único da entidade será gerenciada pelo provedor de persistência. Essa anotação deve ser adicionada logo após a anotação @Id. Quando não anotamos o campo com essa opção, significa que a responsabilidade de gerar e gerenciar as chaves primárias será da aplicação, em outras palavras, do nosso código, como vemos no exemplo a seguir:


@Entity
public class Produto {
 
  @Id @GeneratedValue
  private long id;
 
}

Com o código deste exemplo, a JPA passará a utilizar a estratégia de geração de chave primária do banco de dados ao qual a aplicação está conectada.

strategy

Caso optemos por modificar a estratégia de geração da chave primária, passamos essa informação no atributo strategy de @GeneratedValue. A JPA suporta quatro estratégias, definidas na enum GenerationType e explicadas na tabela a seguir.

Estratégia Descrição
GenerationType.AUTO Valor padrão, deixa com o provedor de persistência a escolha da estratégia mais adequada de acordo com o banco de dados.
GenerationType.IDENTITY Informamos ao provedor de persistência que os valores a serem atribuídos ao identificador único serão gerados pela coluna de auto incremento do banco de dados. Assim, um valor para o identificador é gerado para cada registro inserido no banco. Alguns bancos de dados podem não suportar essa opção.
GenerationType.SEQUENCE Informamos ao provedor de persistência que os valores serão gerados a partir de uma sequence. Caso não seja especificado um nome para a sequence, será utilizada uma sequence padrão, a qual será global, para todas as entidades. Caso uma sequence seja especificada, o provedor passará a adotar essa sequence para criação das chaves primárias. Alguns bancos de dados podem não suportar essa opção.
GenerationType.TABLE Com a opção TABLE é necessário criar uma tabela para gerenciar as chaves primárias. Por causa da sobrecarga de consultas necessárias para manter a tabela atualizada, essa opção é pouco recomendada.

Tabela 1. Estratégias de geração de chave primária suportadas pela JPA.

Nota: A anotação @GeneratedValue faz parte do pacote javax.persistence.

  @Entity
  public class Produto {
   
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
      private long id;
   
      private String nome;
   
      //getters e setters omitidos
   
  }
  

Neste caso, o identificador único será gerado pela coluna de auto incremento do banco de dados.

generator

Caso optemos por trabalhar com a estratégia de geração da chave primária conhecida como SEQUENCE, é comum declararmos outro atributo na anotação @GeneratedValue, o generator. Nele, especificamos um nome para a sequence, e esse mesmo nome será mapeado à sequence do banco de dados através da anotação @SequenceGenerator.

Na seção abaixo apresentamos um exemplo que demonstra como declarar esse atributo.

Exemplo prático

Suponha que criamos a entidade Pessoa e desejamos que o identificador único dessa entidade seja criado por uma sequence do banco de dados. Para isso, podemos fazer o mapeamento conforme o código abaixo:


  @Entity
  public class Pessoa {
                  
  @Id
  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator=”pessoa_sequence”)
  @SequenceGenerator(name=”pessoa_sequence”, sequenceName=”pes_seq”)
      private long id;
      private String cpf;
      private String nome;
   
      //getters e setters omitidos...
   
  }
  

Com a execução desse código será criada uma tabela de nome Pessoa no banco de dados (caso não exista e assim seja configurado) com as colunas id, cpf e nome, sendo id a chave primária cujo valor será gerado pela sequence de nome pes_seq do banco de dados.

Dessa vez, note que em @GeneratedValue também declaramos o atributo generator. Este recebe uma string, o nome da sequence que informamos em @SequenceGenerator. No atributo sequenceName, desta última anotação, apenas passamos o nome da sequence no banco de dados.