【问题标题】:Save successful but Update failed - Many to Many Spring JPA with extra column using Jointable保存成功但更新失败 - 多对多 Spring JPA 与额外列使用 Jointable
【发布时间】:2021-06-11 17:53:22
【问题描述】:

使用 PostRepository 保存方法通过以下方法更新现有实体时出现错误。

这是我的物品,

@Entity
public class Post {
  @Id
  private String postId;
  private String postName;
  @OneToMany(mappedBy = "Post", cascade = CascadeType.ALL)
  private Collection<PostTag> postTags = new HashSet<PostTag>();
}

@Entity
public class Tag {
  @Id
  private String tagId;
  private String tagName;
  @OneToMany(mappedBy = "tag", cascade = CascadeType.ALL)
  @JsonIgnore
  private Collection<PostTag> postTags = new HashSet<PostTag>();
}

@Entity
public class PostTag {
  @EmbeddedId
  private PostTagId postTagId = new PostTagId();
  
  @ManyToOne
  @MapsId("postId")
  @JoinColumn(name = "post_Id")
  @JsonIgnore
  private Post post;
  
  @ManyToOne
  @MapsId("tagId")
  @JoinColumn(name = "tag_Id")
  private Tag tag;
  
  //extra columns ommited
}


@Embeddable
public class PostTagId implements Serializable {
  private String postId;
  private String tagId;
  //equals & hashcode ommited
}

我尝试将帖子保存为以下 POST json 的形式,

{
  "postId": "post-001",
  "postName": "post-001",
  "postTags": [
    {
      "tag": {
        "tagId": "tag-001",
        "tagName": "tag-001"
      }
    }
  ]
}

服务实现如下,

public Post save(Post post){
    Post newPost = new Post();
    newPost.setPostName(Post.getPostName());
    newPost.setPostId(Post.getPostId());
    for (PostTag posttag : post.getPostTags()) {
      PostTag newPostTag = new PostTag();
      Tag dbTag = tagRepo.getById(posttag.getTag().getTagId());
      if(dbTag == null){
        Tag newtag = new Tag();
        newtag.setTagId(posttag.getTag().getTagId());
        newtag.setTagName(posttag.getTag().getTagName());
        tagRepo.save(newTag);
        dbTag = newTag;
      }
      newPostTag.setTag(dbTag);
      newPostTag.setPost(newPost);
      newPost.getPostTags().add(newPostTag);
    }
    return PostRepository.save(newPost);
}

上面的代码第一次工作并在 POST & TAG & POSTTAG 中创建记录。 但是当我使用相同的输入再次运行保存时,它会抱怨以下错误,

javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [PostTagId@c03f34a0]

显然它说 PostId + TagId 组合中已经有一个 obj, 但是,如果已经有相同的组合可用,我怎么能只更新或合并 PostTag 实体额外字段?

请帮忙。

【问题讨论】:

    标签: java spring hibernate jpa many-to-many


    【解决方案1】:

    在下一个链接上已经有同样的问题,所以它可能对你有帮助:answer

    【讨论】:

    • 所以我总是需要根据 posttagid 获取现有的 posttag 并进行修改是吗?为什么不让 hibernate 这样做,如果它已经看到实体就进行更新?
    • 其实只需要使用 save() 来更新现有实体并保存新实体。但我认为错误显示是因为 Post 或 Tag 中的对象没有引用相同的对象 PostTag,而不是引用同一行。或者,您可以通过在列表中搜索并修改它来确保 Tag 和 Post 中的对象引用相同的对象 PostTag。然后你只需要保存 Tag 或 Post 实体。如果您想避免这种情况,您可以删除级联,或指定它(如 CascadeType.REMOVE )。在这种情况下,请确保如果 Post 实体被删除,那么 PostTag 必须被删除到 etc.
    • 感谢您的评论。我从您的评论中的意思是“您可以通过在列表中搜索并修改它来确保 Tag 和 Post 中的对象引用相同的对象 PostTag。”是从数据库中获取 TagPost,如 findBy tagpost 并在顶部进行修改?我说得对吗?
    • 你不必通过搜索TagPost在数据库中找到它,你可以通过它的id找到Tag,然后将PostTag添加到Tag对象中的Collection并保存。我可以看到您在 Tag 和 Post 中定义了对象 PostTag 的集合。这将导致与通过 tag_id 查找指定 PostTag 相同的行为。所以感觉就像你在更新值而不是休眠。在您的代码中已经调用了函数“tagRepo.getById()”,因此您只需要在标签不为空时设置大小写并修改集合od标签(添加或更改PostTag)并保存。
    猜你喜欢
    • 2018-07-09
    • 1970-01-01
    • 2017-08-24
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-10
    相关资源
    最近更新 更多