我有一个实体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
等于null
。 repository.getById(id)
也是如此。再次调用GET之后,客户端会收到正确映射/合并的记录。
问题是:如何持久保存仅知道dictionary.code
的实体,以便休眠状态可以为该记录找到相应的DictionaryEntity
?
我意识到DictionaryEntity
实际上有一个复合键(组,代码)。我可以添加此密钥,但客户端仍然只知道密钥的一部分,而实体则知道第二部分(@Where子句)。我可以自己获取DictionaryEntity
,但是如果我有一个包含200个字段的100个表与dictionary
表联接,该怎么办?我希望解决方案是抽象/通用的。
答案 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?一个仅包含受让人字符串的对象,该字符串仅包含唯一标识受让人的身份:他/她的登录名。
用“配置实体”代替“问题”,用“星期几”代替“受让人”,您的处境与您的情况相同。