使用@JoinColumn保留实体,不指向任何ID属性

时间:2019-05-09 15:41:35

标签: java hibernate jpa

我有一个实体ConfigurationEntity,它的属性dayOfTheWeek的值可以为1-7。客户端获取GET .../configuration时,他们希望同时具有名称和代码(1-7)。关于分解,我创建了一个DictionaryEntity,它映射到存储值的表

id   | group        | name    | code
123  | dayOfTheWeek | Monday  | 1
124  | dayOfTheWeek | Tuesday | 2
etc..

我将ConfigurationEntity定义为

(我省略了一些我认为对问题不重要的细节和注释)

class ConfigurationEntity {
  @Id
  private Long id;

  @ManyToOne
  @JoinColumn(column = "dayOfTheWeek", referenceColum = "code", table = "dictionary")
  @Where("dictionary.group = 'dayOfTheWeek'")
  @JsonIgnore
  private DictionaryEntity dayOfTheWeekDictionary;

  @JsonProperty
  public Number getDayOfTheWeek() {
    return this.dayOfTheWeekDictionary.code;
  }

  @JsonProperty
  public String getDayOfTheWeekDescription() {
    return this.dayOfTheWeekDictionary.name;
  }
}

这有效导致对GET的响应:

{
  "id": 1,
  "dayOfTheWeek": 1,
  "dayOfTheWeekDescription": "Monday"
}

问题是客户希望向ConfigurationEntity提交一些更改并发送以下PATCH请求:

{
  "id": 1,
  "dayOfTheWeek": 2
}

Hibernate / JPA(我通常很困惑,哪个人确实在做什么)可以持续存在(有些黑客),但是repository.save(entity)返回的记录是dayOfTheWeekDictionary等于nullrepository.getById(id)也是如此。再次调用GET之后,客户端会收到正确映射/合并的记录。

问题是:如何持久保存仅知道dictionary.code的实体,以便休眠状态可以为该记录找到相应的DictionaryEntity

我意识到DictionaryEntity实际上有一个复合键(组,代码)。我可以添加此密钥,但客户端仍然只知道密钥的一部分,而实体则知道第二部分(@Where子句)。我可以自己获取DictionaryEntity,但是如果我有一个包含200个字段的100个表与dictionary表联接,该怎么办?我希望解决方案是抽象/通用的。

1 个答案:

答案 0 :(得分:1)

这是一个设计问题。我认为这是错误的,我认为您应该如何解决。

首先:您不需要任何数据库表来指定1是星期一,2是星期二。这应该只是在您的代码中硬编码:这将永远不会改变。您需要做的就是正确定义的枚举和自定义JSON序列化程序,该序列化此枚举的实例到具有代码和日期名称的对象:

"dayOfTheWeek": {
  "code": 1,
  "name": "Monday"
}

该API现在允许修改配置实体。绝对没有理由让任何客户提交一天的名称。目标是更改配置实体,该实体具有星期几,该星期几由数字代码唯一且明确地标识。因此,要更改配置实体的日期,您只需要一个新的日期代码即可。发送新的日期名称既多余又令人困惑(如您的问题所示)。因此,将您的API输入设计为需要日期代码但不需要日期名称的对象。

作为示例,请参阅github REST API。如果您get an issue,作为响应中的问题的一部分,您将得到一个受让人对象,其中包含有关受让人的大量详细信息:标识受让人的登录名,以及他/她的头像,URL等。

但是,如果您提交新的问题,则唯一需要的信息是问题的受让人的ID。授予者的授予名和URL没用,提交它们会造成混淆,因为API不想(也可能不会)更改受让人的详细信息。所以what does the API take as input?一个仅包含受让人字符串的对象,该字符串仅包含唯一标识受让人的身份:他/她的登录名。

用“配置实体”代替“问题”,用“星期几”代替“受让人”,您的处境与您的情况相同。