Enumerated
Explicação
A anotação @Enumerated do JPA é utilizada para mapear atributos do tipo enum em entidades, definindo como seus valores serão armazenados no banco de dados. Existem duas opções principais para o tipo de armazenamento: EnumType.ORDINAL e EnumType.STRING.
@Enumerated
EnumType.ORDINALarmazena o valor do enum como um número inteiro, representando o índice da constante, o que pode ser suscetível a problemas se o enum for alterado (adicionar ou remover valores).EnumType.STRINGarmazena o nome da constante do enum como uma string, oferecendo maior clareza e estabilidade, pois o valor armazenado não depende da posição do enum.
Essa escolha afeta diretamente a forma como os dados são persistidos e a flexibilidade de alterações no código ao longo do tempo.
Isso deve funcionar bem como uma introdução ao tema.
Cenário:
Imagine que temos uma entidade Cliente com os atributos id, nome e estadoCivil, sendo que o estado civil é representado por um tipo enumerado.
Enumeração:
Primeiro, definimos o enum que representa os estados civis:
public enum EstadoCivil {
    SOLTEIRO, CASADO, DIVORCIADO;
}
Classe Cliente:
Aqui está a classe Cliente, com a anotação @Enumerated aplicada ao atributo estadoCivil:
import javax.persistence.*;
@Entity
public class Cliente {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String nome;
    
    @Enumerated(EnumType.STRING)  // Especificando que o valor será armazenado como uma string
    private EstadoCivil estadoCivil;
    // Lombok ou Getters e Setters
}
Particularidades:
- ORDINAL:
 
- Se usarmos 
EnumType.ORDINAL, o JPA vai armazenar o valor do enum como o índice da constante. Ou seja, o primeiro valor será 0, o segundo 1, e assim por diante. 
Exemplo:
@Enumerated(EnumType.ORDINAL)
private EstadoCivil estadoCivil;
Nesse caso, o banco de dados armazenaria os valores como números inteiros:
SOLTEIRO-> 0CASADO-> 1DIVORCIADO-> 2
Cuidado: Isso pode gerar problemas se o enum for alterado (como adicionar ou remover valores), pois os números podem mudar e isso afetaria os dados já armazenados.
- STRING:
 
- Usando 
EnumType.STRING, o JPA armazena o nome da constante do enum como uma string no banco de dados. 
Exemplo:
@Enumerated(EnumType.STRING)
private EstadoCivil estadoCivil;
Nesse caso, o banco de dados armazenaria os valores como strings:
SOLTEIROCASADODIVORCIADO
Vantagem: Usar STRING é mais seguro, pois o valor do enum (nome da constante) permanece claro e não depende de índices numéricos que podem mudar se o enum for alterado.
Resumo:
EnumType.ORDINAL: armazena o índice (inteiro) da constante do enum.EnumType.STRING: armazena o nome da constante do enum como string, o que é mais claro e flexível.
A escolha entre ORDINAL e STRING depende do contexto e da necessidade de manter a integridade dos dados ao longo do tempo.
Converter ID
Se você deseja armazenar o ID do enum no banco de dados (como uma letra abreviada, por exemplo, S, C, D), você pode usar a anotação @Enumerated juntamente com um conversor personalizado.
Vamos adicionar um atributo id ao enum e criar um conversor para mapear o valor para o banco de dados.
- Definindo o enum com ID:
Adicionamos um atributo 
idpara representar o código abreviado de cada estado civil. 
public enum EstadoCivil {
    SOLTEIRO("S"),
    CASADO("C"),
    DIVORCIADO("D"),
    VIÚVO("V");
    private final String id;
    EstadoCivil(String id) {
        this.id = id;
    }
    public String getId() {
        return id;
    }
    public static EstadoCivil fromId(String id) {
        for (EstadoCivil estado : values()) {
            if (estado.getId().equals(id)) {
                return estado;
            }
        }
        throw new IllegalArgumentException("Id não encontrado: " + id);
    }
}
Aqui, cada constante do enum tem um código de identificação (id) associado, como S para SOLTEIRO, C para CASADO, etc.
- Criando um conversor personalizado:
Agora, você pode criar um conversor JPA para armazenar o código (
id) do enum no banco de dados, usando a interfaceAttributeConverter. 
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
@Converter(autoApply = true) // autoApply significa que o conversor será aplicado automaticamente em qualquer atributo do tipo EstadoCivil
public class EstadoCivilConverter implements AttributeConverter<EstadoCivil, String> {
    @Override
    public String convertToDatabaseColumn(EstadoCivil estadoCivil) {
        return estadoCivil != null ? estadoCivil.getId() : null;
    }
    @Override
    public EstadoCivil convertToEntityAttribute(String dbData) {
        return dbData != null ? EstadoCivil.fromId(dbData) : null;
    }
}
- O método 
convertToDatabaseColumnconverte o enum para o código (id) quando o valor é persistido no banco. - O método 
convertToEntityAttributefaz o oposto, convertendo o código de volta para o valor doenumao carregar os dados do banco. 
- Aplicando o conversor na entidade 
Cliente: Agora você pode aplicar a anotação@Enumeratede o conversor na classeCliente. 
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Convert;
@Entity
public class Cliente {
    @Id
    private Long id;
    private String nome;
    
    @Convert(converter = EstadoCivilConverter.class)
    private EstadoCivil estadoCivil;
    // Getters e setters
}
A anotação @Convert especifica que o conversor EstadoCivilConverter será utilizado para o atributo estadoCivil.
No banco de dados
O banco de dados agora armazenará os valores como S, C, D, ou V, ao invés de salvar o nome completo do enum.
Por exemplo:
SOLTEIROserá salvo comoSCASADOserá salvo comoCDIVORCIADOserá salvo comoDVIÚVOserá salvo comoV
Vantagens
- O banco de dados armazena valores mais compactos e legíveis (letras em vez de strings longas).
 - Você ainda mantém a flexibilidade do enum em código (com os nomes completos).
 
Essa estratégia garante que o código seja mais conciso e facilita a conversão entre o banco de dados e os valores do enum de forma transparente.