簡體   English   中英

JPA 具有相同數據庫和額外屬性的多對多關系

[英]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並且您必須在實體上提供equalshashCode 最后,我總是初始化集合值字段(此處為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.

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