在 JPA 2 中实现基于枚举的字典

发布于 2024-12-17 00:12:01 字数 573 浏览 3 评论 0原文

假设我的应用程序中使用了一本字典(即性别:MALE、FEMALE)。

我希望将此字典用作 Java enum。此外,该字典值是从许多其他表中引用的,因此您希望将其设为一个单独的表

Java enum 本身不能是实体。我可以在实体类中使用 enum 属性(注释为 @Enumerated),但这会将枚举(作为整数、字符或字符串)保存在每个中 表使用此enum 而不是使用字典表的 FK。

您将如何实现这样的用例?
- 使用生成 enum 值的静态方法创建一个 Dictionary 实体?
- 修改了 Dictionary 的 getter 和 setter,它返回 enum 而不是 Dictionary 实例?
- ...或者也许您从来不需要在单独的表中保存枚举

Suppose I have a dictionary (i.e. gender: MALE, FEMALE) used in my application.

I'd wish to use this dictionary as a Java enum. Moreover, this dictionary values are referenced from a bunch of other tables, so you'd wish to have it a separate table.

The Java enum cannot be an entity itself. I can use the enum attribute (annotated as @Enumerated) in my Entity classes but this will save the enumeration (as an Integer, char or String) in every table that use this enum instead of using a FK to the dictionary table.

How would you implement such use case?
- Create a Dictionary entity with static method producing enum values?
- Modified getter and setter for Dictionary which returns an enum instead of Dictionary instance?
- ...or perhaps you've never needed to persist an enum in a separate table?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

地狱即天堂 2024-12-24 00:12:01

您可以使用与枚举的序数相匹配的整数ID值来定义字典表。正如许多人所指出的,这是脆弱的,因为您无法轻松修改您的值:在使用 EnumType.ORDINAL @Enumerated 注释上的修饰符。

稍微好一些,您可以指定 EnumType.STRING,并将字典表的主键列定义为 VARCHAR,其值等于 enum的值名称。这仍然很脆弱,因为您无法再更改您的 enum 名称。

此问题的答案显示了另一个选项:坚持使用整数实体,但在您的访问器中进行翻译。

You can define your dictionary table using integer ID values that match the ordinal numbers of your enum. This is fragile, as many have noted, since you cannot then easily modify your values: JPA relies on the ordinal() method when using the EnumType.ORDINAL modifier on your @Enumerated annotation.

Marginally better, you can specify EnumType.STRING, and define the primary key column of your dictionary table as VARCHAR, with values equal to the enum's value names. This is still fragile, in that you cannot any longer change your enum names.

The answer for this question shows another option: Sticking with integers in your entity, but translating in your accessors.

贵在坚持 2024-12-24 00:12:01

这可以通过这种方法来实现。

1.可以存储 ID 的枚举

public enum Gender{
 MALE(1L),
 FEMALE(2L);

private final Long id;

Gender(Long id) {
   this.id= id;
}

public Long getId(){
   return id;
}

2.与此枚举相关的单独实体

public class RefGenderEntity {
    private Long id;
    private String value;
    ......
}

3。查看 EntityManager#findById

MyObjectThatStoreIdForGender val = ...... ;
RefGenderEntity gender = em.find(RefGenderEntity.class, val.getGenderId());

当然,RefGenderEntity 表现在可以预先填充两个值,并且您可以使用外键和常规正常工作连接。

This can be achieved with this approach.

1. Enum where your can store ID

public enum Gender{
 MALE(1L),
 FEMALE(2L);

private final Long id;

Gender(Long id) {
   this.id= id;
}

public Long getId(){
   return id;
}

2. Related to this enum separate Entity

public class RefGenderEntity {
    private Long id;
    private String value;
    ......
}

3. Look at EntityManager#findById

MyObjectThatStoreIdForGender val = ...... ;
RefGenderEntity gender = em.find(RefGenderEntity.class, val.getGenderId());

Of course RefGenderEntity table can now be prepopulated with two values, and your will be fine with foreign keys and regular normal working joins.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文