我想知道如何通过REST调用删除多对多关联。我能够创建记录并关联它们,但不了解如何删除。
我有一个Spring Boot项目,我通过服务和控制器使用REST和HATEOAS直接公开我的存储库。
我有一个用户模型/域类
@Entity
@Table(name = "usr")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Version
private long version = 0;
@Id
@GeneratedValue(generator="optimized-sequence")
private Long id;
@Column(nullable = false, unique = true, length = 500)
@Size(max = 500)
private String userName;
@Column(nullable = false, length = 500)
@Size(max = 500)
private String firstName;
@Column(nullable = false, length = 500)
@Size(max = 500)
private String lastName;
@ManyToMany( fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable( name="user_role",
joinColumns={ @JoinColumn( name = "user_id",
nullable = false
)
},
inverseJoinColumns={ @JoinColumn( name="role_id",
nullable=false
)
}
)
private Set<Role> roles = new HashSet<Role>(0);
...Getters/Setters Below...
正如您所看到的,我有一个角色成员,与Role类是多对多关联,其代码如下:
@Entity
public class Role {
@Id
@GeneratedValue(generator="optimized-sequence")
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String description;
...Getters/Setters Below...
我的存储库看起来像这样:
UserRepository
public interface UserRepository extends
JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
List<User> findByUserName(String username);
}
RoleRepository
public interface RoleRepository
extends JpaRepository<Role, Long> {
}
现在,一切都很顺利。当我从浏览器访问项目根目录时,我获得了JSON + HAL格式的存储库索引/目录。精彩。
(注意我从下面的测试中删除了http://部分,因为StackOverflow将其计入我的链接配额)
我使用WizTools REST客户端,HTTP.POST到角色(localhost:8080 / resttest / roles)存储库并创建一个新角色。成功,角色ID#4已创建。
然后我POST到User存储库创建一个User(localhost:8080 / resttest / users)。成功,用户ID#7创建。
然后我PUT到User存储库以创建与角色的关联:
PUT localhost:8080/resttest/users/7/roles
Content-type: uri-list
Body: localhost:8080/resttest/roles/4
大!协会做了。用户9现在与角色4相关联。
现在我不能为我的生活找出如何删除这种关联。
我使用与上面相同的命令发送HTTP DELETE而不是PUT。
DELETE localhost:8080/resttest/users/7/roles
Content-type: uri-list
Body: localhost:8080/resttest/roles/4
我回来了:HTTP / 1.1 405方法不允许
{
"timestamp":1424827169981,
"status":405,
"error":"Method Not Allowed",
"exception": "org.springframework.web.HttpRequestMethodNotSupportedException",
"message":"Request method 'POST' not supported"
}
答案 0 :(得分:8)
虽然使用剩余元素创建PUT
请求可以解决问题,但DELETE
是一个可以删除关联资源的命令,在大多数情况下更容易使用。
至于你的例子,这应该有效:
DELETE localhost:8080/resttest/users/7/roles/4
另外,在创建关联时,应该在有效负载中包含URI。你不应该在正文中写下整个网址,这应该足够了:
PUT localhost:8080/resttest/users/7/roles
Content-type: uri-list
Body: /roles/4
希望这有帮助。
答案 1 :(得分:1)
来自文档:
DELETE
...
405方法不允许 - 如果关联是非可选的
PUT
表示您替换整个roles
集。因此,要删除单个链接,请PUT
所有剩余链接。如果您只有一个链接并想删除它,那么您将PUT
一个空集合:
PUT localhost:8080/resttest/users/7/roles
Content-type: uri-list
Body:
顺便说一句:你不会发送一个有DELETE
请求的正文。它没有意义。
修改强>
另请参阅Spring HATEOAS开发人员的this answer。