使用Spring Data REST和Spring Data JPA,我想更新聚合根上的子實體集合。舉個例子來說明,假設我有一個Post
實體,它與Comment
實體具有一對多的關係。 Post
擁有自己的Spring數據存儲庫; Comment
不是因爲它只能通過Post
訪問。Spring Data REST/JPA - 使用複合鍵更新OneToMany集合
令人討厭的是Comment
有一個複合鍵,包括由於現有數據庫設計而導致的Post
的外鍵。因此,即使我不需要雙向關係,我也找不到將外鍵作爲Comment
中沒有雙向關係的組合鍵的一部分。
的類看起來像與龍目島標註以下內容:
@Entity
@Data
public class Post {
@Id
@GeneratedValue
private long id;
@OneToMany(mappedBy = "post", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Comment> comments = new HashSet<>();
private String title;
}
和註釋:
@Entity
@IdClass(Comment.CommentPk.class)
@Data
@EqualsAndHashCode(exclude = "post")
@ToString(exclude = "post")
public class Comment {
@Id
private long id;
@Id
@ManyToOne(fetch = FetchType.LAZY)
@RestResource(exported = false)
@JsonIgnore
private Post post;
private String content;
@Data
static class CommentPk implements Serializable {
private long id;
private Post post;
}
}
和知識庫:
public interface PostRepository extends JpaRepository<Post, Long> {
}
如果我嘗試創建一個Post
與Comment
,會發生例外POST_ID
不能爲NULL。換句話說,它正在嘗試持續存在Comment
中的父Post
的反向引用。
這可以通過添加@PrePersist
方法來解決,以Post
維持這種反向參考:
@PrePersist
private void maintainParentBackreference() {
for (Comment comment : this.comments) {
comment.setPost(this);
}
}
創建一個新的Post
時,上述工作正常,但嘗試添加Comment
時,它並不能幫助到現有Post
(例如用PUT請求),因爲試圖插入註釋時將發生以下錯誤:
NULL not allowed for column "POST_ID"; SQL statement:
insert into comment (content, id, post_id) values (?, ?, ?) [23502-193]
回顧一下,步驟REPRO領袖是:
- POST沒有
Comment
小號 - 投入到創建
Post
與一個Post
一個Comment
什麼是我能做到能夠更新的最簡單方法/加Comment
s到使用Spring Data REST的現有Post
?
演示了這方面的一個示例項目可以在這裏找到:https://github.com/shakuzen/aggregate-child-update-sample/tree/composite-key
這種特殊的設置是在倉庫中的composite-key
分支。要重現上述故障與此代碼,你可以按照自述手動再現步驟或運行集成測試AggregateCompositeKeyUpdateTests.canAddCommentWithPut
感謝您的深入響應。如果我可以輕鬆地讓Spring Data REST在處理相應的HTTP請求時使用這些方法,我會很樂意按照您的建議去做,但我不確定如何最好地實現這一點。 –
添加了關於如何使用偵聽器或註釋處理程序回調將我的想法與Spring Data REST集成的信息。 – Naros