2014-03-02 82 views
1

我有一個相當典型的場景,其中有一個主要的@Entity,並且他內部的所有東西都是可嵌入的(所以裏面的所有東西在沒有父母的情況下都沒有意義)。現在JPA 2.0阻止我要嵌套@Embeddable內部的@ElementCollection在另一個@ElementCollection定義:嵌入式和ElementCollection嵌套

JSR-317 嵌入類和基本類型 可嵌入類(包括內的另一可嵌入類的2.6類別可嵌入類)必須不包含元素集合,也不得包含與多對一或一對一關係以外的實體的關係

現在問題是:這是爲什麼?一個簡單的例子:

@Entity 
public class Tournament { 
    @Id 
    Long id; 

    @ElementCollection 
    @CollectionTable 
    private List<Edition>; 
} 

@Embeddable 
public class Edition { 

    @ElementCollection 
    @CollectionTable 
    private List<Round> 
} 

@Embeddable 
public class Round { 

    blabla; 
} 

這是什麼問題?這只是一個例子,你可以將Round和Edition定義爲實體並解決問題,但在我的情況下,出於多種原因,我需要強制執行,如果沒有他的父項,嵌套的東西是沒有意義的。

爲什麼JPA 2.0必須阻止我這麼做?

回答

6

你的情況違反您在粘貼的規格元素:

版本身就是@Embeddable,並含有圓形部分的元素集合,從而:

所包含內可嵌入類(版)元素集合(Tournament.editions)不得包含元素集合(Edition.rounds)。

至於爲什麼你不能這樣做 - 如果你看看http://en.wikibooks.org/wiki/Java_Persistence/ElementCollection的例子,那麼你會看到孩子(版本)將只有一個FK映射回所有者(Tournament.id),而沒有一個自己的ID列 - 理由是作爲一個弱實體,它沒有自己的ID,只能通過參考比賽的ID來定義。

如果這也是一個弱實體,那麼它應該由FK對版本的引用來定義 - 但我們已經說過沒有它自己的ID,所以你不能在DB中映射它而無需在版本中添加標識 - 此時它將成爲一個實體,而不僅僅是@Embeddable。

查看下面的註釋中的維基百科示例 - http://en.wikipedia.org/wiki/Weak_entity - 弱實體的示例有OrderNumber,CustomerNumber等 - 這些東西只有在嵌入另一個對象時纔有意義。

您仍然可以擁有擁有父映射(即版本上的錦標賽參考)和/或雙向引用的實體。您可以強制使用@ManyToOne批註中的nullable = false屬性在版本上定義父級,從而強制執行模型的要求。

+0

正如我在問題中寫到的那樣,模型需要:不應該可以在沒有他的錦標賽的情況下加載版本,並且如果您沒有錦標賽,則不能存在版本。這是ER示意圖中衆所周知的[Weak Entity](弱實體)(http://en.wikipedia.org/wiki/Weak_entity)的概念,但似乎沒有在JPA中很好地實現。 我只是想了解爲什麼在JPA中不能有更多的嵌套可嵌入元素集(可能存在實現問題?),這是在現實世界中描述事物的常用方式。 – Francesco

+0

感謝您的詳細解答。最後,我意識到Embeddable並不完全符合弱實體的想法。一個弱實體應該有一個由外鍵構成的組合主鍵+他自己的id,這對於Embeddable對象來說並不是這種情況。 所以我認爲你給出的最後一個選擇是最合理的,即使我認爲有更直接的東西來映射弱實體,但我錯了。 – Francesco