#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. Теперь это ваше решение.