好的,让我们开始自我引用对象,如下所示:
@Data
@Entity
public class FamilyNode {
@Id
@GeneratedValue
private long id;
private boolean orphan;
@ManyToOne
private FamilyNode parent;
}
这样的标准存储库休息资源:
@RepositoryRestResource(collectionResourceRel = "familynodes", path = "familynodes")
public interface FamilyNodeRepository extends CrudRepository<FamilyNode, Long> {
}
现在,让我们假设我想要链接的一些父对象已经与ID=1
和ID=2
一起存在,每个父对象都是使用POST
创建的/api/familynodes
1}}看起来像这样:
{
"orphan": true,
}
如果我尝试使用对ID=3
的{{1}}请求创建一个具有类似内容的新客户端(POST
),它将在数据库中正常更新链接资源:
/api/familynodes
但是,如果我尝试使用以下正文对{
"orphan": false,
"parent": "/api/familynodes/1"
}
执行PUT
,则父属性似乎默默无效,数据库未更新以反映新关联:
/api/familynodes/3
同样地(这是我正在使用的用例),这样的{
"orphan": false,
"parent": "/api/familynodes/2"
}
只会更新孤儿属性,但不会保持父级不变:
PUT
所以你现在有一个声称是孤儿的记录,但仍有父母。当然,您可以直接对资源URI执行后续REST请求,但我试图使休息操作成为原子,这样任何单个休息查询都无法创建无效状态。所以现在我正在努力解决这个问题,看起来像一个简单的用例而没有编写我自己的控制器来处理它 - 我是否在Spring数据休息领域缺少一个机制?
答案 0 :(得分:0)
这是Spring Data Rest 2.5.7及更高版本中PUT请求的预期行为,其中PUT请求不更新资源链接,仅更新主要属性。
如奥利弗·吉尔克(Oliver Gierke)的详细here:
如果我们考虑有效负载中用于关联字段的URI以更新这些关联,则会出现一个问题:如果未指定URI,将会发生什么情况。就当前行为而言,链接的关联仅属于_links块,因此它们根本不是有效负载的一部分。在这种情况下,我们有两种选择:清除不处理的关联,这会破坏“输入得到的内容”方法。仅擦除使用null提供的内容会模糊“您放置资源的整个状态”。
您可以使用PATCH代替PUT来获得所需的结果