簡體   English   中英

Spring JPA,OneToMany 引用部分主鍵

[英]Spring JPA, OneToMany referencing part of primary key

給定一個 class

@Entity
@Table(name = "ATABLE")
public class A implements Serializable {
    public static final String DB_ID = "AID";
    public static final String DB_MARKET = "AMARKET";

    @EmbeddedId
    @AttributeOverrides({
            @AttributeOverride(name = "id", column = @Column(name = DB_ID)),
            @AttributeOverride(name = "market", column = @Column(name = DB_MARKET))
    })
    public AIdClass id;

    @OneToMany
    @JoinColumn(name = B.DB_MARKET, referencedColumnName = DB_MARKET, insertable = false, updatable = false)
    public List<B> bs;
}

和 B class

@Entity
@Table(name = "BTABLE")
public class B implements Serializable {
    public static final String DB_ID = "BID";
    public static final String DB_MARKET = "BMARKET";

    @EmbeddedId
    @AttributeOverrides({
            @AttributeOverride(name = "id", column = @Column(name = DB_ID)),
            @AttributeOverride(name = "market", column = @Column(name = DB_MARKET))
    })
    public BIdClass id;
}

可能會列出每個實體,但使用該@OneToMany關系確實會引發以下錯誤

org.springframework.beans.factory.BeanCreationException:創建名為“entityManagerFactory”的bean時出錯
引起:org.hibernate.AnnotationException:無法 map 集合 fr.zzz.domain.A.bs
原因:org.hibernate.AnnotationException:fr.zzz.domain.A.bs 的 referencedColumnNames(AMARKET) 引用 fr.zzz.domain.B 未映射到單個屬性

一個A實體與A.AMARKET = B.BMARKET上的多個B相關

您遇到此問題是因為在對鍵 AMARKET = BMARKET 進行連接時,復合鍵 (AID,AMARKET) 和 (BID,BMARKET) 可能不是唯一的。 因此,您得到的錯誤not mapped to a single property 請耐心等待,使用以下示例數據來分析問題;

對於表 A

AID  AMARKET 
 1      1       
 2      1    
 3      2 

對於表 B

BID  BMARKET
 1      1   
 2      2
 3      2

上述情況是絕對可能的(至少在數據庫級別),僅使用AMARKETBMARKET進行連接@OneToMany是不可能的。 不過可以使用@ManyToMany ,如果表結構正確,這將立即解決問題。

但是,如果由於某些業務限制而需要使用@OneToMany 然后您必須更新表 B 以包含A.AID並添加外鍵約束以確保數據完整性。 那么只有結果集對@OneToMany關系有效。 連接將如下所示;

@OneToMany
@JoinColumn(name = B.DB_AID, referencedColumnName = DB_ID)
@JoinColumn(name = B.DB_MARKET, referencedColumnName = DB_MARKET)
public List<B> bs;

在 B 中:

@Entity
@Table(name = "BTABLE")
public class B implements Serializable {
    public static final String DB_ID = "BID";
    public static final String DB_MARKET = "BMARKET";
    public static final String DB_AID = "AID";

    @EmbeddedId
    @AttributeOverrides({
            @AttributeOverride(name = "id", column = @Column(name = DB_ID)),
            @AttributeOverride(name = "market", column = @Column(name = DB_MARKET))
    })
    public BIdClass id;

    @Column(name = DB_AID)
    private Long aid; // assuming aid is a Long
}

現在正在 A 的復合主鍵上完成連接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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