当前位置: 首页 > 知识库问答 >
问题:

在Spring Data Rest中修改@onetomany实体而不使用其存储库

陈昂熙
2023-03-14

在我的项目中,我使用类型A的对象,它与类型B的对象具有一个关系(orphanremove=true,cascade=cascadetype.all,fetch=fetchtype.eagery)。我需要SpringDataRest(SDR)使用单个POST请求存储完整的A对象及其B对象(子对象)。我尝试了SDR中的几种组合,对我来说唯一有效的组合是为对象A创建@repositoryrestresource,也为对象B创建@repositoryrestresource,但将此(B)标记为exported=false(如果我根本没有从对象B创建repository,它将不起作用->只会在单个POST请求上存储一个对象,而不是它的类型B的子对象(@onetomany关系);如果对B存储库省略exported=false会出现同样的结果)。这是否可以,以及实现它的唯一方法(一次存储所有对象的单个POST请求)?

  • “/a/1/b/2”的修补程序不起作用->不允许使用方法(在标题中是“allow:GET,delete”)->所以,也不允许使用
  • json修补程序也不起作用-使用json修补程序内容-type[{“op”:“add”,“path”:“/b/2”,...}]->“目标数组中没有这样的索引”--因为Json补丁在“array”后面使用标量“2”作为数组的索引。这在Java世界中是不实际的,因为关系被保存在一组对象中--索引根本没有意义。
  • 我可以导出对象B的repository(exported=true),以便“直接”操作它,但这样我就不能像我前面提到的那样,在一个POST请求中存储整个对象A及其B对象。

如果可能的话,我希望避免在发送整个A对象时只对其B对象进行一次微小的修改,以便PUT。谢谢你。

共有1个答案

李开宇
2023-03-14

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

@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;
}

我只有一个公开的存储库。

(我的示例使用优秀的HTTPIE-CLI HTTP客户端)

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

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

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

希望这能有所帮助。

 类似资料:
  • 保存“我的实体”时,通过关系工作的子实体不会保存到它们的表中。我不明白怎么回事。 员工: EmployeePhoneNumber: 如何设置这些字段,然后保存实体: 在完成该方法后,我没有一个错误,所有的工作都是正确的,只是表格没有填满--为什么?

  • 我的应用程序中有一个Book model类,它如下所示: 返回NULL。为什么?

  • 我有一个父实体,与其子实体有OneToMany关联: 当我调用方法时,Hibernate不验证children集合@size约束,并按原样保留child“,这导致数据库中的实体无效。 为什么Hibernate不验证父实体?

  • 我创建了一个基本的Spring MVC / JPA / Hibernate应用程序。我试图保存一个UserProfile实体来测试我是否真的可以持久化它,但是什么也没有保存,也没有抛出异常。 在控制器方法中,我创建了一个简单的UserProfile(这是一个@Entity),并将其发送到服务方法。类使用 @Service 对类进行批注,并使用 @Transactional 对 addUserPro

  • 我使用Rails 5.2和GCS作为云服务。我想给用户一个机会来裁剪和旋转用户的图像。用户有许多图像,图像有一个已附加 在开发过程中,我使用以下方法: 但我不知道如何在云中获取图像文件。 我已经将文件下载到本地存储,并完成所有需要的操作。 现在只需要替换(删除当前并创建一个同名的新文件)云中的文件(如果可能的话,不改变数据库记录中的任何内容),但我不知道如何使用活动存储来做到这一点。 至少我需要在

  • 假设我们有一个带有自定义方法的Spring数据存储库接口... 此方法只是设置实体的 deletedAt 字段,ok。有没有办法允许此方法返回 的更新版本? 明显地 …不起作用,因为… java.lang.IllegalArgumentException:修改查询只能使用void或int/Integer作为返回类型! 安宁是否知道另一种轻松允许这种情况的方法,当然除了明显的“在存储库和调用者之间添