Java 保留@JoinColumn不指向任何ID属性的实体
我有一个实体ConfigurationEntity,它的属性DayOfWeek的值可以是1-7。当客户端获取GET…/configuration时,它们希望同时具有名称和代码1-7。关于分解,我创建了一个DictionaryEntity,它映射到存储值的表Java 保留@JoinColumn不指向任何ID属性的实体,java,hibernate,jpa,Java,Hibernate,Jpa,我有一个实体ConfigurationEntity,它的属性DayOfWeek的值可以是1-7。当客户端获取GET…/configuration时,它们希望同时具有名称和代码1-7。关于分解,我创建了一个DictionaryEntity,它映射到存储值的表 id | group | name | code 123 | dayOfTheWeek | Monday | 1 124 | dayOfTheWeek | Tuesday | 2 etc.. 我已将Config
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;
}
}
这项工作的结果是得到:
{
"id": 1,
"dayOfTheWeek": 1,
"dayOfTheWeekDescription": "Monday"
}
问题是当客户端希望向ConfigurationEntity提交一些更改并发送以下修补程序请求时:
{
"id": 1,
"dayOfTheWeek": 2
}
Hibernate/JPA我通常不知道哪一个做了什么,但是repository.saveentity会返回一条DayOfWeekDictionary等于null的记录。repository.getByIdid也是如此。再次调用GET后,客户端接收正确映射/连接的记录
问题是:如何持久化只知道dictionary.code的实体,以便hibernate可以为该记录找到相应的DictionaryEntity
我意识到DictionaryEntity实际上有一个组合键组code。我可以添加这个密钥,但客户端只知道密钥的一部分,实体知道第二部分@Where子句。我可以自己获取DictionaryEntity,但如果我有一个100个表,其中200个字段与DictionaryTable连接,该怎么办?我希望解决方案是抽象/通用的。这是一个设计问题。以下是我认为错误的地方,以及我认为你应该如何解决这个问题 第一:不需要任何数据库表来指定1是星期一,2是星期二。这应该简单地在代码中硬编码:这永远不会改变。您所需要的只是一个正确定义的枚举和一个自定义JSON序列化程序,该序列化程序将此枚举的实例序列化为一个对象,其中包含代码和日期:
"dayOfTheWeek": {
"code": 1,
"name": "Monday"
}
现在介绍允许修改配置实体的API。绝对没有理由让任何客户提交日期名称。目标是更改一个配置实体,该实体有一周中的一天,该天由数字代码唯一且明确地标识。因此,要更改配置实体的日期,只需要一个新的日期代码。如你的问题所示,发送一个新的日期名称既多余又令人困惑。因此,将您的API输入设计为一个需要日代码的对象,但不需要日名称
例如,请参见github REST API。如果您将在响应中得到一个assignee对象,其中包含有关assignee的大量详细信息:标识assignee的登录名,以及他/她的gravatar、URL等
但是,如果您提交一个新的问题,唯一需要的信息是该问题的受让人的ID。gravatar和受让人的URL是无用的,提交它们会让人感到困惑,因为API不希望也可能不会更改受让人的详细信息。所以仅包含受让人字符串的对象,该字符串仅包含唯一标识受让人的内容:他/她的登录名
按配置实体替换问题,按工作日替换受让人,您的情况与您的情况相同。是的,我不需要它作为工作日的名称,但这只是一个示例,可能不太合适。它不能硬编码,因为这将改变。名称可以在任何给定时刻更改,并且可以有新的值。将dictionary表视为前端选择列表选项的存储。我不明白你在第一段代码片段下的意思。这正是我要问的:M point仍然代表您的dopdown选项。选项的标签仅在显示选项时有用。当客户端想要选择其中一个选项时,它应该提交的唯一内容是标识该选项的ID或代码。不是它的标签,它不应该改变,是无用的。因此,从客户端发送的JSON文档中获取提交选项的代码,然后使用JPA从数据库中获取相应的DictionaryEntity,使用查询按代码和组查找实体,然后使用找到的DictionaryEntity更新yoyr实体。我不会使用单个表来存储不相关的信息,顺便说一句,只需使用一个单独的表,映射到一个单独的实体,允许在将来根据需要为每个实体添加其他属性。周数没有理由存储在与客户类别相同的表中,或者可以在下拉列表中选择任何其他内容。是。我希望客户只提交代码,而不是标签。问题是如何通过这段代码以泛型/抽象的方式获取DictionaryEntity,这样我就不必显式重写每个save方法并获取dictionary。我希望Hibernate使用注释来实现这一点。它不应该是通用的。如果提交的代码应该是一周中某一天的代码,那么您应该获取并验证一周中某一天的代码 d不是任何其他类型的实体。Hibernate允许管理持久层。它不是处理RESTful API的工具。不要把这两层混在一起。