簡體   English   中英

JPA - 使用一對多關系數組列表更新實體

[英]JPA - update entity with one to many relationship array list

假設我正在更新與 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"
       },
  ]
}

這是我在請求正文中傳遞的內容,以使用 1 的 Id 更新用戶

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

用戶實體

 @OneToMany(
            cascade = CascadeType.ALL,
            orphanRemoval = true,
            fetch = FetchType.LAZY
 )
 @JoinColumn(
            name = "user_id",
            foreignKey = @ForeignKey(name = "fk_post_id"),
            referencedColumnName = "userId"
 )
 private List<Post> post = new ArrayList<>();

您明確調用user.getPosts().clear() ,但您對只有新帖子存在感到驚訝?

您還需要注意userrepository.save(user)返回合並的結果,您需要從您的方法中返回該結果,以便將最新的表示形式序列化為 JSON。

https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html?is-external=true#save-S-

保存給定的實體。 使用返回的實例進行進一步的操作,因為保存操作可能已經完全改變了實體實例。

變化:

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().addAll(mappedUser.getPost());

據我所知,Hibernate 建議將 Collection 接口用於一對多關系。 在這種方法中,addAll 不會將現有的帖子元素與新聞合並。 因此,您的集合中將有重復的帖子。 addAll 僅在您 100% 確定 mappingUser 僅包含新元素的情況下才起作用。 但如果它不正確,那么您將需要手動合並或清除以前的集合以避免重復。 不建議清除收集。 因為clear意味着hibernate會刪除所有記錄,然后重新創建。

只有在您選擇 Set like collection 的情況下,您的方式才會起作用。 也不推薦這樣做,因為 set require 來計算 hashcode。 要做到這一點,休眠將需要從數據庫中獲取所有記錄。 想象一下,您有 3000 個帖子供一個用戶使用。 然后你添加一個新的來設置...... Hibernate 需要獲取所有 3000 個帖子以確保新的帖子是唯一的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM