【问题标题】:Is there a way of using a lookup table as a converter in JPA?有没有办法在 JPA 中使用查找表作为转换器?
【发布时间】:2023-09-20 13:40:01
【问题描述】:

假设我有一个简单的实体如下:

@Entity
@Table(name = "PERSON")
public class Person {

@Id
@Column(name = "NAME")
private String name;

@Column(name = "GENDER")
private String gender;
}

还有两个表,保存信息的实际表和一个查找表。

TABLE PERSON (
NAME VARCHAR2 NOT NULL,
GENDER INT NOT NULL);

TABLE GENDER_LOOKUP (
GENDER_ID INT NOT NULL,
GENDER_NAME VARCHAR2 NOTNULL);

我想将我实体中的信息保存到表中,以便将字符串字段gender自动转换为对应的gender int,使用查找表作为参考。我想到了两种方法,但我想知道是否有更有效的方法。

  1. 创建一个枚举并使用序数枚举来持久化。我宁愿避免这种情况,因为我希望信息只有一个“真实来源”,并且出于各种商业原因,它必须是一个查找表。

  2. 使用@Converter 注解并编写自定义转换器。我认为这需要我查询表以提取相关行,因此这意味着每次转换某些内容时我都必须对数据库进行 JPA 调用。

我目前正计划使用 2,但我想知道是否有任何方法可以在数据库本身中执行此操作,因为我认为使用 JPA 执行所有这些操作的成本高于我在数据库中执行所有操作的成本数据库。本质上是尝试持久化一个字符串性别,然后数据库会查看查找表并将其转换为正确的 Id 并保存。

我专门使用 openJpa,但希望这不是特定于实现的。

【问题讨论】:

    标签: java database jpa openjpa


    【解决方案1】:

    由于您认真考虑过使用enum,这意味着GENDER_LOOKUP 是静态的,即程序运行时内容不会改变。

    因此,您应该使用选项 2,但在第一次查找时让转换器缓存/加载来自 GENDER_LOOKUP 的所有记录。这样一来,您仍然只有一个“事实来源”,而无需在每次查找时都访问数据库。

    如果您需要添加新的性别1,您只需重启应用即可刷新缓存。

    1) 如今,谁知道需要哪些新性别。

    【讨论】:

    • 谢谢,这很有意义。
    最近更新 更多