JPA Hibernate以人类可读的格式保留任何Enum(一个Map键)?

时间:2014-11-13 12:05:02

标签: hibernate jpa map enums

假设你有一个类需要保存一些映射项,使用任何枚举作为键。使用此映射可以生成例如具有十六进制值的varbinary(SQL Server)。

@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)或可用于恢复枚举而不是十六进制值的清晰内容?

1 个答案:

答案 0 :(得分:3)

要存储一个其中key是枚举的Map,并在db中获取人类可读的内容,您可以尝试:

@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的实体或值。 在此示例中,映射值为type: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);
总而言之,你可以通过你的枚举来获取

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

请注意事务,LazyException和那些东西。