簡體   English   中英

JPA/Hibernate:如何將復合外鍵與部分主鍵相關聯

[英]JPA/Hibernate: How to associate composite foreign keys with partial primary keys

我有兩個表,每個表都有一個組合鍵:

CREATE TABLE Software (
  id int not null,
  version int not null,
  PRIMARY KEY (id, version)
);

CREATE TABLE System (
  name char(10) not null,
  version int not null,
  PRIMARY KEY (name, version)
);

現在,我需要一個關聯來表達“軟件對其可以運行的系統版本有最低要求”的概念。 下表在數據庫級別執行此操作:

CREATE TABLE Requirement (
  software_id int not null,
  software_version int not null,
  system_name char(10) not null,
  system_version int not null,
  PRIMARY KEY (software_id, software_version, system_name),
  FOREIGN KEY (software_id, software_version) REFERENCES Software (id,version),
  FOREIGN KEY (system_name, system_version) REFERENCES System (name,version)
)

請注意,Requirement 有三個字段作為主鍵。 如果我要使所有四個主要,那么我可以表達對軟件的不止一個要求(即 OpenLib v1.2 依賴於 Ubuntu 13.04 和 Ubuntu 13.10),而一個軟件對於給定的操作系統只能有一個要求(在例如,OpenLib v1.2 依賴於 Ubuntu 13.04)。

如何將其映射到 JPA/Hibernate @Entity 對象(使用注釋)? (包括相關的 OneToMany/ManyToOne 關聯。)

我面臨的主要問題是只有部分系統鍵用作需求中的主鍵。

注意:我不必遵守特定的遺留數據庫,因此可以修改數據庫設計。 我也對 @EmbeddedId 和/或 @IdClass 解決方案持開放態度。 不過,我更喜歡遵守 JPA。

我的代碼中的屬性需要通過 getter/setter 映射,而不是直接通過字段映射,但我想只使用字段的解決方案就可以了,只要轉換是直接的。

謝謝你。

** 編輯 28/8/2014 **

考慮以下我用來測試給出的解決方案的簡單測試場景:

Software software = new Software(1,10);
System system = new System(2,20);
session.save(software);
session.save(system);
Requirement req = new Requirement();
req.setSoftware(software);
req.setSystem(system);
session.save(req);

您可以按如下方式編寫Requirement類:

@Entity
public class Requirement {

    @EmbeddedId
    private RequirementKey id;

    @ManyToOne
    @JoinColumns({
            @JoinColumn(name = "name", referencedColumnName = "name", 
                        insertable = false, updatable = false),
            @JoinColumn(name = "system_version",
                        referencedColumnName = "version",
                        insertable = false, updatable = false)
    })
    private System system;

    @ManyToOne
    @JoinColumns({
            @JoinColumn(name = "id", referencedColumnName = "id", 
                        insertable = false, updatable = false),
            @JoinColumn(name = "version", 
                        referencedColumnName = "version",
                        insertable = false, updatable = false)
    })
    private Software software;

}

使用RequirementKey

@Embeddable
public class RequirementKey implements Serializable {
    int id;
    int version;
    String name;
}

我認為有更好的解決方案,但我無法弄清楚如何做到這一點。

暫無
暫無

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

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