JPA 休眠 以人类可读的格式保留任何枚举(映射键)



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

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

这有效,但主要问题是可读性。数据库中的数据不是人类可读的。尝试使用 @MapKeyEnumerated(EnumType.STRING) 或与 EnumType.Ordinal 一起使用不起作用,因为枚举可以是任何类型,并且将MyEnum.SOME_VALUE保存为"SOME_VALUE"。

是否可以拦截保存/检索并保存完全限定的名称(com.x.myenum.value)或可用于恢复枚举而不是十六进制值的清晰名称?

要存储一个键是枚举的 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>();
... }

其中,问卷定义翻译是给定语言枚举的实体或值。在此示例中,映射值的类型为:问卷定义翻译

@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之类的东西。

最新更新