[英]How do I cascade persist an @OneToMany relationship with an @EmbeddedId using Spring Data / Hibernate
我已經看到很多類似的問題被問到,但還沒有找到解決我所看到的問題的解決方案,所以如果這是一個多余的問題,請提前道歉。 在我的情況下,我有各種類型的實體,它們每個都有自己的標簽關聯。 所以我想要一個通用的 Tag 類,它不會有自己的 id,而是一個 id/復合鍵,由它標記的實體的 id 和標簽類型組成。 為了(嘗試)實現這一點,我創建了一個@Embeddable
id 類:
@Embeddable
public class TagId implements Serializable {
@Column(columnDefinition = "BINARY(16)")
private UUID parentId;
private String value;
// Getters, setters...
}
該 Id 反過來被@MappedSuperclass
:
@MappedSuperClass
public class Tag {
@EmbeddedId
private TagId id;
// Other attributes, getters, setters...
}
...然后當我想標記特定實體時,例如使用 BookTag,該表將有一個book_id
列作為 Book 表的外鍵,代替parentId
:
@Entity
@Table(name = "book_tag")
@AttributeOverride(name = "parentId", column = @Column(name = "book_id"))
public class BookTag extends Tag {
// other attributes, getters, setters...
}
最后,我有一個 Book 實體:
@Entity
@Table(name = "book")
public class Book {
@Id
@GeneratedValue
@Column(columnDefinition = "Binary(16)")
private UUID id;
// other attributes, getters, setters...
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "id.parentId")
private List<BookTag> tags;
}
然后,當我嘗試使用填充的 BookTag 集合保存新 Book 時,使用 Spring Data JPA 存儲庫repo.save(book)
,我想要的行為是保存 Book,然后將 id 復制到 BookTag 對象,那些被保存了。 不幸的是,我在日志中看到的是 Book 按預期插入,然后運行 Tag 對象的插入,但book_id
被綁定為每個條目的null
。
我嘗試了其他一些方法:
parentId
@GeneratedValue沒有任何效果,但我的語法可能已關閉。 預先感謝任何知道如何解決此問題的人。
對於任何想做類似事情的人,我終於找到了符合我標准的解決方案。
TagId 修改為:
@Embeddable
public class TagId<T> implements Serializable {
@ManyToOne
private T parent;
private String value;
// Getters, setters...
}
......這導致對標簽的輕微修改......
@MappedSuperClass
public class Tag<T> {
@EmbeddedId
private TagId id;
// Other attributes, getters, setters...
}
...然后BookTag...
@Entity
@Table(name = "book_tag")
@AttributeOverride(name = "parent", column = @Column(name = "book_id"))
public class BookTag extends Tag<Book> {
// other attributes, getters, setters...
}
...最后預訂:
@Entity
@Table(name = "book")
public class Book {
@Id
@GeneratedValue
@Column(columnDefinition = "Binary(16)")
private UUID id;
// other attributes, getters, setters...
@JoinColumn(name = "book_id", referencedColumnName = "id")
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<BookTag> tags;
}
現在我可以將 1...* BookTags 添加到 Book,然后我必須在所有 BookTags 上設置 Book,但是這是對 bookRepository.save() 的一次調用,並且所有內容都向下級聯。 用 id 來做會更好,但泛型足夠靈活。 我只會讓它實現一個接口,以便 toString/hashCode/equals 可以在父級上調用 getId。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.