Как сохранить тип перечисления как строчную строку?

Мой класс модели (часть):

public class User ... {

    @Enumerated(STRING)
    private Status status;

    ...

    public enum Status {

        ACTIVE,
        INACTIVE;

        @Override
        public String toString() {
            return this.name().toLowerCase();
        }
    }

    ...

    public String getStatus() {
        return status.name().toLowerCase();
    }

    public void setStatus(Status status) {
        this.status = status;
    }
}

Как вы видите выше, я переопределяю метод toString, но никакого эффекта. Перечисление хранится в базе данных как ACTIVE или INACTIVE.

P.S. Я использую hibernate jpa

Спасибо за помощь!

P.S.S. Я спрашиваю, потому что я пишу службу REST, которая создает json (в json-объекте лучше использовать строчный регистр, если я не ошибаюсь)

Ответ 1

напишите класс converter, аннотированный с помощью @Converter, который реализует javax.persistence.AttributeConverter<YourEnum, String>. Существует два метода:

public String convertToDatabaseColumn(YourEnum attribute){..}
public YourEnum convertToEntityAttribute(String dbData) {..}

там вы можете применить свою логику верхнего/нижнего регистра.

Позже вы можете аннотировать ваше поле, используя данный преобразователь.

Ответ 2

Вот быстрый и практический пример использования AttributeConverter (представлен в JPA 2.1)

Обновите свой enum класс:

public enum Status {
    ACTIVE,
    INACTIVE;

    public String toDbValue() {
        return this.name().toLowerCase();
    }

    public static Status from(String status) {
        // Note: error if null, error if not "ACTIVE" nor "INACTIVE"
        return Status.valueOf(status.toUpperCase());
    }
}

Создать конвертер атрибутов:

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

@Converter(autoApply = true)
public class StatusConverter implements AttributeConverter<Status, String> {
    @Override
    public String convertToDatabaseColumn(Status status) {
        return status.toDbValue();
    }

    @Override
    public Status convertToEntityAttribute(String dbData) {
        return Status.from(dbData);
    }
}

Если для autoApply установлено значение true, вам не нужно добавлять аннотацию javax.persistence.Convert ко всем атрибутам, которые должны быть преобразованы. В противном случае примените конвертер:

import javax.persistence.Convert;
import javax.persistence.Entity;

@Entity
public class User {

    @Convert(converter = StatusConverter.class)
    @Enumerated(STRING)
    private Status status;

    // ... other fields, constructor(s), standard accessors
}

Ответ 3

Лучше всего использовать верхний регистр для констант перечисления.

Я вижу две опции

  • Используйте нижний регистр в перечислении (не очень хорошая практика).
  • Измените метод getter (метод getStatus) bean, используя это перечисление, чтобы вернуть нижний регистр. (наилучший возможный вариант)

Ответ 4

Вы можете определить поле в классе User как String. И когда вы сохраняете сущность в хранилище, используйте перечислимый класс для проверки значения:

User user = new User(Status.valueOf(status.toUpperCase()).toString().toLowerCase())