2012-12-11 42 views
0

我有〜10個類,每個類都有複合鍵,由2-4個值組成。 其中1個類是主要類(我們稱之爲「中心」),與其他類相關爲一對一或一對多。JPA - 真正的主鍵生成引用的ID

想到在JPA中描述這種方法的正確方法我想我需要使用@Embedded/@PrimaryKey註釋來描述所有主鍵。

問題1: 我擔心的是 - 它意味着,在數據庫級別上,我會在每個表中的其他列指的是「中心」等於「中心」列數的# PK?

如果是,是否可以通過使用一些人爲的唯一鍵來避免它參考?您能否介紹一下在這種情況下如何描述真正的PK和人爲的PK?

注:爲什麼我要保持真正的PK,而不是隻使用唯一的ID作爲PK的原因 - 我的應用程序有從外部數據源的一些數據加載功能,有時他們可能會返回的記錄,我已在本地數據庫中。如果唯一ID將用作PK - 對於新記錄,我將無法進行數據更新,因爲唯一ID將不可用於剛下載的數據。同時,這對於應用程序來說是正常情況,它只需要更新插入新記錄取決於真實複合主鍵是否匹配。

問題2: 10類的所有具有I,其中它們中的每一個延伸抽象類描述的公共字段「日期」。 「日期」本身永遠不是關鍵,但它總是每個類的組合鍵的一部分。每個班的複合鍵是不同的。 爲了能夠使用這個字段作爲PK的一部分,我應該在每個類中描述它,還是有任何方法可以按原樣使用它? 我嘗試了@Embedded和@PrimaryKey註釋,並且總是得到eclipselink找不到抽象類中描述的字段的錯誤。

預先感謝您!

PS。我正在使用最新版本的eclipselink & H2數據庫。

回答

1

見,

http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Composite_Primary_Keys

對於信息複合鍵。

通常使用單個生成的ID更好,但如果您有遺留數據,則可以使用複合鍵。

我不會推薦使用@EmbeddedId,而是使用@IdClass,這會簡單得多。 EclipseLink不需要@IdClass,但如果你想使用find(),那麼你需要一個組合鍵值。

您應該可以使用@MappedSuperclass定義其中一個id字段,確保您使用@Id註釋每個關鍵字段。

EclipseLink允許使用@PrimaryKey註解來簡化指定組合鍵,您只需要提供列的列表。您仍然必須將這些列映射到您班級的屬性中。

3

我的建議:忘記功能組合鍵:它們效率低下,而且是一個噩夢。只需爲所有實體使用單列自動生成的密鑰。這也會使您的桌子變得更短,更乾淨(列數更少)。

這並不妨礙您在一組列上創建唯一約束,以確保例如對於列col1,col2和col3只有一個帶有a,b和c的記錄。

如果你想檢查的記錄已經存在於A,B,C,剛剛創建的查詢:

select center from Center center 
where center.col1 = :col1 
and center.col2 = :col2 
and center.col3 = :col3 
+0

謝謝。我使用@Table(uniqueConstraints = {..來定義複合唯一鍵。關於檢查對象是否已經存在的方法 - 我以塊加載對象,每個對象都有〜400個實例,有時約50%是新的, 〜50%匹配唯一密鑰,需要更新。我正在考慮避免50%的chuck額外的選擇語句,只需要更新它,如果唯一的密鑰匹配....你看到任何方式來做到這一點比運行選擇更有效? – Val