2014-11-13 2 views
0

Скажите, что у вас есть класс, который должен сохранять некоторые отображаемые объекты, используя любой Enum для ключа. Используя это отображение, оно генерирует, например. varbinary (SQL Server) с шестнадцатеричным значением.JPA Hibernate Персистировать любой Enum (ключ карты) в человекообразном формате?

@Entity 
public abstract class X { 
    @ElementCollection 
    private Map<Enum, Boolean> values; 
} 

Это работает, но главная проблема - читаемость. Данные в базе данных не читаются человеком. пытаясь использовать @MapKeyEnumerated(EnumType.STRING) или с EnumType.Ordinal не работает, так как Enum может быть любым типом и который сохраняет MyEnum.SOME_VALUE как «SOME_VALUE».

Возможно ли перехватить сохранение/извлечение и сохранить полное имя (com.x.myenum.value) или что-то разборчивое, которое можно было бы использовать для восстановления перечисления вместо шестнадцатеричного значения?

ответ

2

Чтобы сохранить карту, где ключ является перечислением, и получить что-то удобочитаемое в дб, вы можете попробовать:

@Entity 
public class QuestionnaireDefinition{ 
    ... 
    @OneToMany(mappedBy = "questionnaireDefinition", fetch = FetchType.LAZY, cascade = CascadeType.ALL) 
    @MapKeyEnumerated(EnumType.STRING) 
    @MapKeyColumn(name = "language", insertable = false, updatable = false) 
    private final Map<Language, QuestionnaireDefinitionTranslation> translations = new HashMap<Language, QuestionnaireDefinitionTranslation>(); 
... } 

где QuestionnaireDefinitionTranslation является юридическим лицом или значения, которое будет fecthed данной языковой ENUM. В этом примере значение карта типа: QuestionnaireDefinitionTranslation

@Entity 
public class QuestionnaireDefinitionTranslation { 

    @Enumerated(EnumType.STRING) 
    @Column(nullable = false, insertable = true, updatable = true)  
    private Language language; 

    @ManyToOne(fetch = FetchType.LAZY, optional = false) 
    private QuestionnaireDefinition questionnaireDefinition; 

    private String text; 
    ... 
} 

Класс языка является обычным перечисление:

public enum Language { 
    EN, ES, FI, FR; 
} 

Идея сделать эту работу: 1. Сначала сохраняется класс с владельцем :

QuestionnaireDefinition questionnaireDef = new QuestionnaireDefinition(); 
em.persist(questionnaireDef); 

, а затем агрегированный класс с использованием перечисления в качестве ключа.

QuestionnaireDefinitionTranslation translation = new QuestionnaireDefinitionTranslation(); 
translation.set(questionnaireDef); 
translation.setLanguage(Language.En); 
translation.setText("hello"); 
em.persist(translation); 

voilá это все, вы можете получить известный вашим перечислимого

QuestionnaireDefinition qd = em.find(1,QuestionnaireDefinition.class); 
qd.getTranslations().get(Language.EN); 

Будьте в курсе с транзакциями, LazyException и что вещи.

Смежные вопросы