Jas*_*ain 4 java spring hibernate h2
我的Comment实体是自加入的,有一个subComment集合。
@Entity
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
@OneToMany(mappedBy = "parentComment", cascade = CascadeType.ALL)
private Set<Comment> subComments = new HashSet<>();
@ManyToOne
@JoinColumn(referencedColumnName = "id")
private Comment parentComment;
Run Code Online (Sandbox Code Playgroud)
在我的addComment方法中
public ResponseEntity<Comment> addComment(Comment comment) {
Comment currComment = commentRepository.save(comment);
if (currComment.getParentId() != null) {
Comment parent = commentRepository.findById(currComment.getParentId()).orElse(null);
if (parent != null) {
parent.addSubComment(currComment);
currComment.setParentId(parent.getId());
currComment.setParentComment(parent);
commentRepository.save(parent);
}
}
Comment responseComment = commentRepository.save(currComment);
return ResponseEntity.ok(responseComment);
}
Run Code Online (Sandbox Code Playgroud)
当我尝试建立反向关系(拥有方)时,
comment.setParentComment(parent);导致错误
comment.setParentComment(parent); 导致错误: java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
完整评论实体类
@OneToMany(mappedBy = "parentComment", cascade = CascadeType.ALL)
private Set<Comment> subComments = new HashSet<>();
@ManyToOne
@JoinColumn(referencedColumnName = "id")
private Comment parentComment;
private boolean isParent;
private String parentId;
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public Set<Comment> getSubComments() {
return subComments;
}
public void setSubComments(Set<Comment> subComments) {
this.subComments = subComments;
}
public Comment addSubComment(Comment comment) {
this.subComments.add(comment);
return this;
}
public Comment getParentComment() {
return parentComment;
}
public void setParentComment(Comment parentComment) {
this.parentComment = parentComment;
}
public boolean getIsParent() {
return isParent;
}
public void setIsParent(boolean isParent) {
this.isParent = isParent;
}
Run Code Online (Sandbox Code Playgroud)
@ManyToOne
@JoinColumn(referencedColumnName = "id")
@JsonBackReference
private Comment parentComment;
Run Code Online (Sandbox Code Playgroud)
我添加了解决java.lang.IllegalStateException: Cannot call sendError() after the response has been committed错误的@JsonBackReference 。父母Comment也能够看到该subComments集合。
你似乎把它复杂化了。
1) 你有@JoinColumn(referencedColumnName = "id")但那是多余的。无论如何,这就是外键引用的内容,因此您无需明确说明。不用担心,但不要编写不需要的代码。
2) 如果您在新的子评论中有 parentId,则不需要查找它并将其添加到父评论的列表中。您在这里缺少的概念是“拥有”实体概念。查看 Javadoc for mappedBy. 由于该parentComment字段进行映射,因此它定义了拥有实体。当然,它是同一个实体,但关键是它parentComment是控制持久性的字段。您无需向Setof添加任何内容即可subComments保持关系。如果需要,您可以这样做,但 JPA 会忽略它。您只需要设置parentComment字段。例如
编辑:这个例子是用 JPA 而不是 Spring Data,但它在引擎盖下是一样的。
您的实体只需:
@Entity
public class Comment {
@Id @GeneratedValue
private Integer id;
@OneToMany(mappedBy="parentComment")
private Set<Comment> subComments;
@ManyToOne
private Comment parentComment;
Run Code Online (Sandbox Code Playgroud)
你像这样使用它:
private void run() {
runWrite();
runRead();
Comment comment = new Comment();
comment.setId(1);
Comment subComment = new Comment();
subComment.setParentComment(comment);
runSaveSubComment(subComment);
runRead();
}
private void runWrite() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistence");
em = emf.createEntityManager();
tx = em.getTransaction();
try {
tx.begin();
Comment comment = new Comment();
Comment subComment = new Comment();
subComment.setParentComment(comment);
em.persist(comment);
em.persist(subComment);
tx.commit();
} finally {
emf.close();
}
}
private void runRead() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistence");
em = emf.createEntityManager();
try {
Comment comment = em.createQuery("select c from Comment c left join fetch c.subComments where c.id = :id", Comment.class).setParameter("id", 1).getSingleResult();
System.out.println(comment + Arrays.toString( comment.getSubComments().toArray()) );
} finally {
emf.close();
}
}
private void runSaveSubComment(Comment subComment) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistence");
em = emf.createEntityManager();
tx = em.getTransaction();
try {
tx.begin();
em.persist(subComment);
tx.commit();
} finally {
emf.close();
}
}
Run Code Online (Sandbox Code Playgroud)
或者如果您想使用 Spring Data。
Comment comment = new Comment();
Comment sub1 = new Comment();
sub1.setParentComment(comment);
repo.save(comment);
repo.save(sub1);
Comment parentComment = repo.fetchSubCommentsById(1);
System.out.println(parentComment + Arrays.toString(parentComment.getSubComments().toArray()));
Comment sub2 = new Comment();
sub2.setParentComment(parentComment);
repo.save(sub2);
parentComment = repo.fetchSubCommentsById(1);
System.out.println(parentComment + Arrays.toString(parentComment.getSubComments().toArray()));
// or
Comment p = new Comment();
p.setId(1);
Comment sub3 = new Comment();
sub3.setParentComment(p);
repo.save(sub3);
parentComment = repo.fetchSubCommentsById(1);
System.out.println(parentComment + Arrays.toString(parentComment.getSubComments().toArray()));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10137 次 |
| 最近记录: |