Есть ли способ сохранить «расширенное перечисление» с помощью JPA

#java #spring-boot #jpa #enums

Вопрос:

Есть ли способ сохранить «расширенное перечисление» с помощью JPA ?
Я работаю с абстрактным объектом в своем проекте spring boot, и мой базовый объект может иметь несколько состояний. Объект, расширяющий его, может иметь базовое состояние, но также и другие конкретные состояния. Вы не можете расширяться enum в Java, поэтому мой первый опыт использования interface метода по умолчанию isCommon для разграничения между моими общими значениями перечисления и моими расширенными значениями перечисления в моих службах.
Однако я больше не могу использовать аннотацию @Enumerated в своем свойстве. Есть ли способ заставить его работать или другой шаблон, который я мог бы использовать ?
Небольшой пример кода для обеспечения некоторого контекста :

 @Entity
abstract class AbstractFoo {
   public StateInterface state;
}

@Entity
class ConcreteFoo extends AbstractFoo {

}

@Service
class ConcreteFooService {
    public boolean isCommonState(ConcreteFoo foo) {
        return foo.state.isCommon();
    }
}

interface StateInterface {
   default boolean isCommon() {
       return false;
   }
}

enum CommonState extends StateInterface {
   BEGIN, END;
   
   @Override
   boolean isCommon() {
      return true;
   }
}

enum SpecificState extends StateInterface {
    MIDDLE;
}
 

Ответ №1:

Я бы предложил вам вместо этого использовать следующее перечисление:

 enum State {
    BEGIN(true), MIDDLE(false), END(true);

    private final boolean common;

    State(boolean common) {
        this.common = common;
    }

    public boolean isCommon() {
       return common;
    }
}
 

Для вашего случая использования это лучшее, что я могу придумать.

Комментарии:

1. Да, но это нарушает расширяемость моего пакета! Я хочу иметь возможность добавлять и удалять состояния, не затрагивая ядро моего приложения

2. Как вы узнали из своих попыток, если вы используете интерфейс для эмуляции расширяемости перечисления, вы не сможете использовать @Enumerated аннотации, связанные с JPA. Так что вам придется пойти на компромисс. Либо у вас есть расширяемые перечисления и вы применяете некоторую черную магию, чтобы они легко работали с JPA, либо у вас есть одно перечисление с дополнительным параметром, который вам нужно будет изменять всякий раз, когда это необходимо, и просто использовать @Enumerated для его обработки JPA. Теперь это ваше решение.