Org.hibernate.InstantiationException: нет конструктора по умолчанию для объекта: com.domain.AnomalieAck

Я пытаюсь сохранить значение enum в базе данных, но возникает исключение создания экземпляра, вот мое сопоставление:

@Entity
public class Anomalie {

    @Embedded
    private AnomalieAck ack = AnomalieAck.NON_ACQUITTEE;



    public Anomalie() {
    }
/*getters and setters*/
}

//AnomalieAck.java

public enum AnomalieAck {

    NON_ACQUITTEE(0),

    ACQUITTEE_APP1 (1),

    ACQUITTEE_APP2(2),

    /** Aacquittee en erreur. */
    ACQUITTEE_ERREUR(10),

    @Column(name = "ANO_ACK")
    private int ack = 0;

  private AnomalieAck() {

    }

  private AnomalieAck(final int value) {
    this.ack = value;
   }
  public int getValue() {
        return this.ack;
    }
  public void setAck(int ack) {
        this.ack = ack;
    }
}

Причина, по которой я не использовал @Enumerated(EnumType.STRING) или @Enumerated(EnumType.ORDINAL), заключается в том, что в базе данных поле ANO_ACK объявлено как число, и есть много других ресурсов, которые используют это значение как число.

Все проверил: конструктор без аргументов уже определен, метод setter реализован.

Что я могу сделать, чтобы Hibernate создал экземпляр этого класса?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
958
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Не вставляйте перечисление.

Здесь вам нужен специальный конвертер:

Конвертер:

@Converter
public class AnomalieAckConverter implements AttributeConverter<AnomalieAck , Integer> {

 @Override
 public String convertToDatabaseColumn(AnomalieAck  anomalieAck ) {
   return anomalieAck.getValue();
 }

 @Override
 public AnomalieAck convertToEntityAttribute(Integer ack) {
    retrun AnomalieAck.getByValue(ack);
 }

}

Сущность:

@Column
@Convert(converter = AnomalieAckConverter.class)
private AnomalieAck ack;

Спасибо за ваш ответ, но должен ли я создать интерфейс AttributeConverter?

Zakaria Marrah 04.04.2019 11:49

Нет. Это часть пакета javax.persistence.

Maciej Kowalski 04.04.2019 11:50

вам может понадобиться добавить зависимость hibernate-jpa-2.1-api к вашему проекту

Maciej Kowalski 04.04.2019 11:51

Это работает, большое спасибо, но в базе данных, когда значение ack сохраняется, оно принимает порядковое значение вместо самого значения. Что я могу сделать, чтобы сохранить значение вместо порядкового номера? Он работает так, как если бы я использовал (EnumType.Ordinal)

Zakaria Marrah 04.04.2019 15:07

создайте метод getAck в перечислении и используйте его вместо этого

Maciej Kowalski 04.04.2019 15:12

Я сделал это, имя метода в моем классе — getValue(), и я не могу переименовать его, потому что он используется в других внешних продуктах. Не могли бы вы понять, почему это песистирует порядковое значение.

Zakaria Marrah 04.04.2019 15:32

Класс перечисления

public enum AnomalieAck {

    NON_ACQUITTEE(0),

    ACQUITTEE_APP1 (1),

    ACQUITTEE_APP2(2),

    /** Aacquittee en erreur. */
    ACQUITTEE_ERREUR(10),


    private int ack = 0;

  private AnomalieAck() {

    }

  private AnomalieAck(final int value) {
    this.ack = value;
   }
  public int getValue() {
        return this.ack;
    }

  public void setAck(int ack) {
        this.ack = ack;
    }

public static AnomalieAck getByValue(int ackNumero) {
    for (final AnomalieAck ackitement : AnomalieAck.values()) {

        if (ackitement.getValue() == ackNumero) {
            return ackitement;
        }
    }

    return null;
}

}

Преобразователь:

public class AnomalieAckConverter implements AttributeConverter<AnomalieAck, Integer> {

    /**
     * @param attribute
     * @return
     * @see javax.persistence.AttributeConverter#convertToDatabaseColumn(java.lang.Object)
     */
    @Override
    public Integer convertToDatabaseColumn(AnomalieAck anoAck) {
        // TODO Auto-generated method stub
        return anoAck.getValue();
    }

    /**
     * @param dbData
     * @return
     * @see javax.persistence.AttributeConverter#convertToEntityAttribute(java.lang.Object)
     */
    @Override
    public AnomalieAck convertToEntityAttribute(Integer ack) {
        // TODO Auto-generated method stub
        return AnomalieAck.getByValue(ack);

    }

Решение работает, но оно сохраняет порядковое значение вместо значения int, getAck — это getValue()

Другие вопросы по теме