簡體   English   中英

如何使用 Spring Data / Hibernate 級聯保持 @OneToMany 與 @EmbeddedId 的關系

[英]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

我嘗試了其他一些方法:

  1. @JoinColumn 而不是mappedBy
  2. @MapsId 帶有對 BookTag 上 Book 的 @ManyToOne 引用
  3. 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.

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