在我的项目中,我使用类型 A 的对象,它具有OneToMany关系(orphanRemoval = true,cascade = CascadeType.ALL,fetch = FetchType.EAGER)到 B类型的对象。我需要SpringDataRest(SDR)使用单个POST请求存储完整的 A 对象及其 B 对象(子)。我在SDR中尝试了几种组合,唯一对我有用的组合是为对象 A 创建@RepositoryRestResource,并为对象 B 创建@RepositoryRestResource,但是标记为( B )as exported = false(如果我根本没有从对象 B 创建存储库,它将无效 - >只是 A 对象将存储在单个POST请求中,但不存储其类型 B 的子级(@OneToMany关系);如果 B 存储库省略exported = false,则会出现相同的结果)。 这是否可行并且是如何实现它的唯一方法(单个POST请求同时存储所有对象)?
我之所以要问,在我之前的例子中,我必须(我想)控制所有对象"生命周期"使用 A 的存储库。我很好,因为 A - > B 关系是组合( B 不存在于 A )。但是我有严重的问题,即使用其父存储库由SDR编辑(也删除)某个 B 类型的对象(因为对象 B 没有自己的存储库导出)。也许,根据定义,这是不可能的。我尝试过这些解决方案:
如果可能的话,我想避免发送整个 A 对象,对其PUT的 B 对象进行一次微小修改。 谢谢。
答案 0 :(得分:5)
我设法更改了子实体,如下所示。作为样本,我使用了以下实体:
@Entity
@Data
@NoArgsConstructor
public class One {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToMany(cascade = ALL)
private List<Many> manies = new ArrayList<>();
}
@Entity
@Data
@NoArgsConstructor
public class Many {
public Many(String name) {
this.name = name;
}
@Id
@GeneratedValue
private Long id;
private String name;
}
我只有One
暴露的存储库。
(我的例子使用优秀的httpie - CLI HTTP client)
使用json补丁删除项目
此示例将删除manies列表中的第二项。您可以使用@OrderColumn确保您可以依赖列表项的顺序。
echo '[{"op":"remove", "path":"/manies/1"}]' | http PATCH :8080/ones/1 Content-Type:application/json-patch+json -v
PATCH /ones/1 HTTP/1.1
Content-Type: application/json-patch+json
[
{
"op": "remove",
"path": "/manies/1"
}
]
使用json补丁替换整个列表
此示例使用值中指定的数组替换列表。
echo '[{"op":"add", "path":"/manies", "value":[{"name":"3"}]}]' | http PATCH :8080/ones/1 Content-Type:application/json-patch+json -v
PATCH /ones/1 HTTP/1.1
Accept: application/json
Content-Type: application/json-patch+json
[
{
"op": "add",
"path": "/manies",
"value": [
{
"name": "3"
}
]
}
]
使用json patch
将项目添加到列表中此示例将项添加到列表的末尾。此外,客户端只需要在更新之前知道列表的长度。所以订单在这里并不重要。
echo '[{"op":"add", "path":"/manies/-", "value":{"name":"4"}}]' | http PATCH :8080/ones/1 Content-Type:application/json-patch+json -v
PATCH /ones/1 HTTP/1.1
Accept: application/json
Content-Type: application/json-patch+json
[
{
"op": "add",
"path": "/manies/-",
"value": {
"name": "4"
}
}
]
希望这有帮助。