[英]JPA Many-To-Many Relationship with same DB and extra Attribute
我需要同一個數據庫中的多對多關系。 我不介意創建映射數據庫,但我希望最終只有一個實體。
假設我有一個可以有很多資源(子資源)的資源。 我需要的是一個帶有子資源的資源以及它們的數量,因為一個資源可以有 x 個資源。
本質上,我需要此資源所需的子資源計數的額外屬性。
@Table(name = "resources")
public class Resources {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column
private String name;
@ManyToMany
private Collection<Resources> subResources;
}
為了澄清一點,充其量我會有類似的東西:
@Table(name = "resources")
public class Resources {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column
private String name;
@ManyToMany
private HashMap<Resources, Integer /* count */> subResources;
}
我知道它是如何與兩個表(資源和子資源)和一個映射類型一起工作的,但我不知道如何按照上述方式進行操作,因為資源可以同時是子資源。
提前致謝
編輯:我需要映射表中的一個額外屬性,我可以在其中將子資源的數量設置為 Integer
您擁有的配置將適用於單向關系。 沒有技術問題,只是你不能指定一個子資源的多個父母,所以最終不是多對多。
為了使其真正成為多對多,您需要Resources
class上的另一個字段來定義關系的反面; 我添加了@JoinTable
注釋以明確連接表中的名稱,但如果默認值對您來說足夠好,則它是可選的; 我也從不同的基本Collection
切換到List
; 我更喜歡Set
並且您必須在實體上提供equals
和hashCode
。 最后,我總是初始化集合值字段(此處為ArrayList
;如果您使用 go 為Set
,則為HashSet
),以避免愚蠢的NullPointerException
或復雜的初始化代碼:
@ManyToMany
@JoinTable(
name = "RESOURCE_SUBRESOURCE",
joinColumns = @JoinColumn(name = "resource_id"),
inverseJoinColumns = @JoinColumn(name = "subresource_id")
)
private List<Resource> subResources = new ArrayList<>();
// the mappedBy signals that this is the inverse side of the relation, not a new relation altogether
@ManyToMany(mappedBy = "subResources")
private List<Resource> parentResources = new ArrayList<>();
用於:
Resources r1 = new Resources();
r1.setName("alpha");
em.persist(r1);
Resources r2 = new Resources();
r2.setName("beta");
r2.getSubResources().add(r1);
em.persist(r2);
Resources r3 = new Resources();
r3.setName("gama");
em.persist(r3);
Resources r4 = new Resources();
r4.setName("delta");
// won't work, you need to set the owning side of the relationship, not the inverse:
r4.setParentResources(Arrays.asList(r2, r3));
// will work like this:
r2.getSubResources().add(r4);
r3.getSubResources().add(r4);
// I believe that the order of the following operations is important, unless you set cascade on the relationship
em.persist(r4);
r2 = em.merge(r2);
r3 = em.merge(r3);
至於計數:在您提到您想要相關對象的計數的問題中。 雖然特定的 JPA 提供程序(Hibernate、EclipseLink)可能允許您完成此操作(使用由聚合查詢填充的只讀字段 - COUNT(*) FROM JoinTable WHERE resource_id=?
),但它不是標准的。 您總是可以執行resource.getSubResources().size()
,但這會將所有子資源提取到 memory 中,這不是一件好事,如果您經常調用或有很多子/父資源。
每當我真正需要它時,我寧願運行一個單獨的計數查詢,甚至可能是一組資源 ID。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.