gpt4 book ai didi

spring - 处理@RepositoryRestResource 中的多对多关系

转载 作者:行者123 更新时间:2023-12-03 17:36:27 30 4
gpt4 key购买 nike

前言

我想在一次调用中创建另一个资源的子资源。这些资源有@ManyToMany关系:用户和组。

不要想先创建一个用户,然后是组,然后是关系,如 Working with Relationships in Spring Data REST 所示- 仅仅因为我认为不能单独存在的资源(例如组)只有在至少有一个用户也与该资源相关联时才应该创建。为此,我需要一个端点 like this one (这对我不起作用,否则我不会在这里)创建一个组并在一个事务中设置关联的“播种”用户。

目前,使这项工作对我有用的唯一方法是像这样手动“同步”关系:

public void setUsers(Set<AppUser> users) {
users.forEach(u -> u.getGroups().add(this));
this.users = users;
}

这将使我能够
POST http://localhost:8080/groups

{
"name": "Group X",
"users": ["http://localhost:8080/users/1"]
}

但我的问题是这对我来说感觉不对 - 这似乎是一种解决方法,而不是使此要求起作用的实际 Spring 方式。所以 ..

我目前正在努力使用 Spring 的 @RepositoryRestResource 创建关系资源.我想创建一个新组并将其与调用用户相关联,如下所示:
POST http://localhost:8080/users/1/groups

{
"name": "Group X"
}

但唯一的结果是响应 204 No Content .我不知道为什么。这可能与我的另一个问题(见 here)有关,也可能无关,我试图通过在 JSON 负载中设置相关资源来实现相同的目标 - 这也不起作用。

服务器端我收到以下错误:
tion$ResourceSupportHttpMessageConverter : Failed to evaluate Jackson deserialization for type [[simple type, class org.springframework.hateoas.Resources<java.lang.Object>]]: java.lang.NullPointerException

如果您需要任何特定代码,请告诉我。

试过

我加了 exported = false@RepositoryRestResourceUserGroupRepository :
@RepositoryRestResource(collectionResourceRel = "groups", path = "groups", exported = false)
public interface UserGroupRepository extends JpaRepository<UserGroup, Long> {
List<UserGroup> findByName(@Param("name") String name);
}

我正在发送:
PATCH http://localhost:8080/users/1

{
"groups": [
{
"name": "Group X"
}
]
}

然而,结果仍然只是 204 No Content和一个 ResourceNotFoundException在服务器端。

单元测试

本质上,下面的单元测试应该可以工作,但我也可以接受为什么这不能工作的答案,这也说明了这是如何正确完成的。
@Autowired
private TestRestTemplate template;

private static String USERS_ENDPOINT = "http://localhost:8080/users/";
private static String GROUPS_ENDPOINT = "http://localhost:8080/groups/";

// ..

@Test
@DirtiesContext(classMode = ClassMode.BEFORE_EACH_TEST_METHOD)
public void whenCreateUserGroup() {

// Creates a user
whenCreateAppUser();

ResponseEntity<AppUser> appUserResponse = template.getForEntity(USERS_ENDPOINT + "1/", AppUser.class);
AppUser appUser = appUserResponse.getBody();

UserGroup userGroup = new UserGroup();
userGroup.setName("Test Group");
userGroup.setUsers(Collections.singleton(appUser));

template.postForEntity(GROUPS_ENDPOINT, userGroup, UserGroup.class);

ResponseEntity<UserGroup> userGroupResponse = template.getForEntity(GROUPS_ENDPOINT + "2/", UserGroup.class);

Predicate<String> username = other -> appUser.getUsername().equals(other);

assertNotNull("Response must not be null.", userGroupResponse.getBody());

assertTrue("User was not associated with the group he created.",
userGroupResponse.getBody().getUsers().stream()
.map(AppUser::getUsername).anyMatch(username));
}

然而,该行
userGroup.setUsers(Collections.singleton(appUser)); 

将破坏此测试并返回 404 Bad Request .

最佳答案

根据 SDR reference :

POST

Only supported for collection associations. Adds a new element to the collection. Supported media types:

text/uri-list - URIs pointing to the resource to add to the association.


所以添加 groupuser尝试这样做:
POST http://localhost:8080/users/1/groups (with Content-Type:text/uri-list)
http://localhost:8080/groups/1
附加 info .

关于spring - 处理@RepositoryRestResource 中的多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47377464/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com