簡體   English   中英

Hibernate:insertable = false,updatable = false屬於涉及外鍵的復合主鍵星座?

[英]Hibernate: Where do insertable = false, updatable = false belong in composite primary key constellations involving foreign keys?

在Hibernate或其他ORM中實現復合主鍵時,最多有三個位置將insertable = false,updatable = false放在使用標識關系的復合主鍵星座中(FK是PK的一部分):

  1. 進入復合PK類'@Column注釋(僅限@Embeddable類)或
  2. 進入實體類'association @ JoinColumn / s注釋或
  3. 進入實體類' 冗余 PK屬性的@Column注釋(僅限@IdClass類)

第三種是使用@IdClass和JPA 1.0 AFAIK的唯一方法。 請參閱http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Primary_Keys_through_OneToOne_Relationships 我只會考慮案例1.和2。

問:將“insertable = false,updatable = false”置於一般的首選位置是哪種方式?

我遇到過關於這個問題的Hibernate問題。 例如,Hibernate 3.5.x會抱怨Zips表

CREATE TABLE Zips
(
  country_code CHAR(2),
  code VARCHAR(10),
  PRIMARY KEY (country_code, code),
  FOREIGN KEY (country_code) REFERENCES Countries (iso_code)
)

有:

org.hibernate.MappingException: Repeated column in mapping for entity: com.kawoolutions.bbstats.model.Zip column: country_code (should be mapped with insert="false" update="false")
org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:676)
org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:698)
...

如您所見,country_code列是PK和FK。 這是它的類:

實體類:

@Entity
@Table(name = "Zips")
public class Zip implements Serializable
{
    @EmbeddedId
    private ZipId id;

    @ManyToOne
    @JoinColumn(name = "country_code", referencedColumnName = "iso_code")
    private Country country = null;
...
}

復合PK類:

@Embeddable
public class ZipId implements Serializable
{
    @Column(name = "country_code", insertable = false, updatable = false)
    private String countryCode;

    @Column(name = "code")
    private String code;
...
}

將insertable = false,updatable = false放入實體類關聯的@JoinColumn時,所有異常都會消失,一切正常。 但是,我不明白為什么上面的代碼不應該工作。 可能是Hibernate有這個問題。 是描述了一個Hibernate錯誤,因為它似乎沒有評估@Column“insertable = false,updatable = false”?

從本質上講,標准的JPA方式,最佳實踐或偏好在哪里放置“insertable = false,updatable = false”?

讓我一步一步回答。

1.什么時候需要`insertable = false,updatable = false`?

讓我們看看下面的映射,

public class Zip {

    @ManyToOne
    @JoinColumn(name = "country_code", referencedColumnName = "iso_code")
    private Country country = null

    @Column(name = "country_code")
    private String countryCode;

}

這里我們使用兩個不同的屬性來引用表中的相同列。 在下面的代碼中,

Zip z = new Zip();

z.setCountry(getCountry("US"));
z.setCountryCode("IN");

saveZip(z);

冬眠會在這里做什么?

為了防止這種不一致,hibernate要求你指定關系船的更新點。 這意味着你可以參考表中的同一列n的次數,但只有其中一個可以用來更新和所有其他人將是只讀的

2.為什么hibernate抱怨你的映射?

Zip類中,您指的是嵌入式id類ZipId ,它再次包含國家/地區代碼。 如上所述,您現在可以從兩個位置更新counry_code列。 因此,hibernate給出的錯誤是正確的。

3.如何解決你的情況?

不。理想情況下,您希望ZipId類生成id,因此不應將insertable = false, updatable = false ZipId insertable = false, updatable = falseZipId內的countryCode。 所以修復如下修改Zip類中的country映射,如下所示,

@ManyToOne
@JoinColumn(name = "country_code", referencedColumnName = "iso_code",
insertable =  false, updatable = false)
private Country country;

希望這有助於您的理解。

您還可以使用@PrimaryKeyJoinColumn批注來解決此問題。 PrimaryKeyJoinColumn批注指定主鍵列,該列用作連接到另一個表的外鍵。

PrimaryKeyJoinColumn批注用於將JOINED映射策略中實體子類的主表連接到其超類的主表; 它在SecondaryTable注釋中用於將輔助表連接到主表; 它可以用在OneToOne映射中,其中引用實體的主鍵用作引用實體的外鍵。 如果在JOINED映射策略中沒有為子類指定PrimaryKeyJoinColumn批注,則假定外鍵列具有與超類主表的主鍵列相同的名稱。

暫無
暫無

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

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