修改Spring Data Rest中没有其存储库的@OneToMany实体

在我的项目中,我使用类型为A的对象,该对象具有类型B的对象的OneToMany关系(orphanRemoval = true,cascade = CascadeType.ALL,fetch = FetchType.EAGER)。 我需要SpringDataRest(SDR)使用单个POST请求来存储完整的完整A对象及其B对象(子对象)。 我在SDR中尝试了几种组合,唯一对我有用的组合是为对象A创建@RepositoryRestResource并为对象B创建@RepositoryRestResource,但是将此( B )标记为exported = false(如果我没有创建存储库)在对象B之外 ,它将无法工作 – >只是一个对象将存储在单个POST请求中,而不是它的子类型(@OneToMany关系)类型B ;如果B存储库省略了exported = false,则会出现相同的结果)。 这是否正确,是如何实现它的唯一方法(单个POST请求同时存储所有对象)?

我之所以要问,在我之前的例子中,我必须(我想)通过使用A的存储库来控制所有对象“生命周期”。 我很好,因为A – > B关系是组合( B不存在于A之外)。 但是我有严重的问题,即使用其父存储库通过SDR编辑(也删除) B类型的某个对象(因为对象B没有导出自己的存储库)。 也许,根据定义,这是不可能的。 我试过这些解决方案:

  • “/ A / 1 / B / 2”的PATCH不起作用 – >方法不允许(在标题中是“允许:GET,DELETE”) – >所以,PUT也是不可能的
  • 使用json补丁内容类型[{“op”:“添加”,“路径”:“/ B / 2”,….}] – > JCH补丁无效 – PATCH为“/ A / 1” “目标数组中没有这样的索引” – 因为Json Patch在“数组”之后使用标量“2”作为其数组的索引。 这在Java世界中是不实际的,当关系保存在对象集中时 – 索引根本没有任何意义。
  • 我可以导出对象B的存储库(exported = true)以“直接”操作它,但是这样我就会失去将整个对象A及其B对象存储在一个POST请求中的能力,如前所述。

如果可能的话,我想避免用PUT的一个微小的B对象修改来发送整个A对象。 谢谢。

我设法改变子实体如下。 作为示例,我使用了以下实体:

@Entity @Data @NoArgsConstructor public class One { @Id @GeneratedValue private Long id; private String name; @OneToMany(cascade = ALL) private List 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客户端 )

使用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补丁将项添加到列表中

此示例将项添加到列表的末尾。 此外,客户端只需要在更新之前知道列表的长度。 所以订单在这里并不重要。

 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" } } ] 

希望这可以帮助。