Java JPA-使用一对多关系数组列表更新实体

Java JPA-使用一对多关系数组列表更新实体,java,spring-boot,jpa,spring-data-jpa,Java,Spring Boot,Jpa,Spring Data Jpa,假设我正在更新与post有一对多关系的用户实体 这是更新的代码 public User updateUser(Long userid, Userdto userdto) { User user = findByTemplatesFooterNo(userid); User mappedUser = modelmapper.map(UserDto, User.class); user.setName(mappedUser.getName()); user.setA

假设我正在更新与post有一对多关系的用户实体

这是更新的代码

public User updateUser(Long userid, Userdto userdto) {
    User user = findByTemplatesFooterNo(userid);
    User mappedUser = modelmapper.map(UserDto, User.class);

    user.setName(mappedUser.getName());
    user.setAge(mappedUser.getAge());

    user.getPosts().clear();
    user.getPosts().addAll(mappedUser.getPost());

    userrepository.save(user);
}
这是用户的当前数据

{
  "user_id" : 1,
  "name" : "testname",
  "age" : "testage",
  "posts" : [
       {
            "post_id" : 1,
            "title" : "titlepost",
            "content" : "content"
       },
       {
            "post_id" : 2,
            "title" : "titlepost",
            "content" : "content"
       },
  ]
}
这是我在请求主体上传递的内容,用于更新Id为1的用户

{
  "name" : "testname",
  "age" : "testage",
  "posts" : [
       {
            "title" : "titlepost",
            "content" : "content"
       }    
  ]
}
我可以成功地更新用户,并且响应为

{
  "user_id" : 1,
  "name" : "testname",
  "age" : "testage",
  "posts" : [
       {
            "post_id" : 3,
            "title" : "titlepost",
            "content" : "content"
       }    
  ]
}
它将替换当前的所有帖子。我想要的只是附加新的,这样响应就会

{
      "user_id" : 1,
      "name" : "testname",
      "age" : "testage",
      "posts" : [
           {
                "post_id" : 1,
                "title" : "titlepost",
                "content" : "content"
           },
           {
                "post_id" : 2,
                "title" : "titlepost",
                "content" : "content"
           },
           {
                "post_id" : 3,
                "title" : "titlepost",
                "content" : "content"
           },
      ]
}
用户实体

您显式地调用user.getPosts.clear,但却惊讶地发现只有新的post存在

您还需要知道userrepository.saveuser返回合并结果,并且您需要从方法返回合并结果,以便将最新的表示形式序列化为JSON

保存给定的实体。将返回的实例用于进一步的操作 因为保存操作可能已更改实体实例 完全是

变化:

public User updateUser(Long userid, Userdto userdto) {
    User user = findByTemplatesFooterNo(userid);
    User mappedUser = modelmapper.map(UserDto, User.class);

    user.setName(mappedUser.getName());
    user.setAge(mappedUser.getAge());

    //user.getPosts().clear(); <-- WHY?
    user.getPosts().addAll(mappedUser.getPost());

    return userrepository.save(user); // <-- return the result of the merge
}
user.getPosts.addAllmappedUser.getPost

据我所知,Hibernate建议对一对多关系使用集合接口。 通过这种方法,addAll不会将现有的posts元素与news合并。 因此,您将在集合中有重复的帖子。 只有在100%确定mappedUser只包含新元素的情况下,addAll才会起作用。但如果不正确,则需要手动合并或清除以前的集合以避免重复。不建议清除收集。因为清除意味着hibernate将删除所有记录,然后再次创建它

只有在您选择“类似集合”的情况下,您的方式才会起作用。 但也不建议这样做,因为set需要计算hashcode。为此,hibernate需要从数据库中获取所有记录。
假设一个用户有3000篇文章。然后你添加一个新的设置。。。Hibernate需要获得所有3000篇文章,以确保新文章是唯一的。

您需要按id 1获取用户,比较并保存整个对象。比较是什么意思?im按id获取用户1更正,按id获取现有帖子的用户。将现有职位与新职位进行比较。如果传入的帖子是newcomparison,则将其附加到现有列表中。Parison可能会说不存在,并再次保存整个用户对象。任何示例都可以启动?问题是,当我在帖子中更新特定id时,它不会更新,并且会出错,因为帖子将使用相同id保存两次,这就是为什么我需要首先清除它?在savingOkay之前,你应该问一个问题,而不是你认为的解决方案。
public User updateUser(Long userid, Userdto userdto) {
    User user = findByTemplatesFooterNo(userid);
    User mappedUser = modelmapper.map(UserDto, User.class);

    user.setName(mappedUser.getName());
    user.setAge(mappedUser.getAge());

    //user.getPosts().clear(); <-- WHY?
    user.getPosts().addAll(mappedUser.getPost());

    return userrepository.save(user); // <-- return the result of the merge
}