@Enumerated(Enumtype.STRING) Hibernate JPA

Asked

Viewed 2,036 times

5

I have the following field classificacao in a table.

This field is filled in elsewhere and is filled with, only, 'P' or 'N', acronyms for Positive and Negative.

I then created the enum Java.

Classificacao.

public enum Classificacao {
    POSITIVO('P'), NEGATIVO('N');

    private char classificacao;

    Classificacao(char classificacao) {
        this.classificacao = classificacao;
    }

    public char getClassificacao() {
        return classificacao;
    }
}

In my entity, I have the attribute:

@Enumerated(EnumType.STRING)
@Convert(converter = ClassificacaoEnumConverter.class)
@Column(name = "classificacao", length = 1)
private Classificacao classificacao;

When I try to list this table, the following Exception is launched:

java.lang.IllegalArgumentException: Unknown name value [N] for enum class [br.com.jpalab.enums.Classificacao]

I understand why, from his mistake, he seeks the value N, where there is only POSTIVO and NEGATIVO, but how could I solve this problem?

I created this Converter

@Converter
public class ClassificacaoEnumConverter implements AttributeConverter<Classificacao, String> {

    @Override
    public String convertToDatabaseColumn(Classificacao classificacao) {
        return String.valueOf(classificacao.getClassificacao());
    }

    @Override
    public Classificacao convertToEntityAttribute(String classificacaoFromDb) {
        if (classificacao == null) return null;
        switch (classificacaoFromDb) {
            case "P":
                return Classificacao.POSITIVO;
            case "N":
                return Classificacao.NEGATIVO;
        }

        throw new IllegalStateException();
    }
}

1 answer

3


Try using a Converter with a AttributeConverter:

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

public enum Classificacao {
    POSITIVO('P'), NEGATIVO('N');

    private final char classificacao;

    Classificacao(char classificacao) {
        this.classificacao = classificacao;
    }

    public char getClassificacao() {
        return classificacao;
    }

    @Converter(autoApply = true)
    public static class Mapeador implements AttributeConverter<Classificacao, String> {

        @Override
        public String convertToDatabaseColumn(Classificacao x) {
            return String.valueOf(x.getClassificacao());
        }

        @Override
        public Classificacao convertToEntityAttribute(String y) {
            if (y == null) return null;
            if ("P".equals(y)) return POSITIVO;
            if ("N".equals(y)) return NEGATIVO;
            throw new IllegalStateException("Valor inválido: " + y);
        }
    }
}
import javax.persistence.Convert;

// ...

    //@Enumerated(EnumType.STRING)
    @Convert(converter = Classificacao.Mapeador.class)
    @Column(name = "classificacao", length = 1)
    private Classificacao classificacao;

Note that the @Enumerated was removed from the mapping.

  • Without converting it shouldn’t be enough? At least for JPA is, iirc.

  • @Gustavocinque Hence the name() of each element of enum would have to be persisted. That is, instead of just being P and N in the database, it would have to be POSITIVO and NEGATIVO.

  • True, only after I commented that I realized there was a difference in what the author wanted as Enum’s name and what was going to the bank.

  • I already tried to use Converter, it keeps launching the same Exception

  • It was faster than me :). Alternatively we can create a table CLASSIFICACAO with ID and NOME. Then we can create a FK in the table that uses the Enum referencing CLASSIFICACAO.CLASSIFICAO_ID and map with @Column(name="CLASSIFICAO_ID") &#xA;@Enumerated(EnumType.ORDINAL). The advantage is that if the Enum change in some way (e.g., if you rename or add values) is much easier to make the change, although it creates problems if you reorder the members of Enum only on the Java side.

  • @Henriquesantiago tried the @Converter(autoApply = true)?

  • @Victorstafusa yes, inclusive, I put a log and debugged, the methods of the interface Attribute Converter are not even being called.

  • the autoapply = true is for when you want to do this for all attributes that have Rating, even setting the convert in the @Convert annotation, IE, being redundant, does not work

  • @Henriquesantiago What is the version of your JPA? And Hibernate?

  • <hibernate-entitymanager.version>5.2.10.Final</hibernate-entitymanager.version>

  • I only have this dependency, I have no dependency on jpa

  • I took the note of @Enumerated and it worked.

  • --' :( :D --' ( :D

  • @Henriquesantiago KKKKK - That is, it has to be Converter without Enumerated.

  • @Henriquesantiago Reply edited.

  • exact, puts! kkkkkkk

Show 11 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.