2013-04-30 76 views
1

摘要雙向one-to-多對一關係

說,我有兩個簡單的@Entity繼承樹(一個抽象基類,有兩個具體的實現類在每個樹中)InheritanceType.TABLE_PER_CLASS;我需要一個使用@JoinColumn連接基類的雙向@OneToMany關係。

這應該會產生四個表,每個具體類一個,對嗎? EclipseLink爲其中一個抽象基類生成第五個表,這對我來說沒有意義。考慮這個例子(這不是一個現實世界的例子,它只是對JPA):

收藏是@OneToMany關係的第一繼承樹和執行者的抽象根:

@Entity 
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) 
public abstract class Collection { 
    @Id @GeneratedValue 
    public long id; 
    @OneToMany(mappedBy="collection") 
    public List<Media> items = new ArrayList<Media>(); 
} 

PhysicalCollection和VirtualCollection是收集的具體實現:

@Entity 
public class PhysicalCollection extends Collection {} 

@Entity 
public class VirtualCollection extends Collection {} 

媒體是@ManyToOne關係的第二繼承樹和實現者的抽象根:

@Entity 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
public abstract class Media { 
    @Id 
    @GeneratedValue 
    public long id; 
    @ManyToOne 
    @JoinColumn(nullable = false) 
    public Collection collection; 
} 

CdMedia和TapeMedia是媒體的具體實施方式:

@Entity 
public class CdMedia extends Media {} 

@Entity 
public class TapeMedia extends Media {} 

RESULT

作爲我說過,EclipseLink將從此生成五個表(不介意SEQUENCE表):

mysql> SHOW TABLES; 
+--------------------+ 
| Tables_in_test  | 
+--------------------+ 
| CDMEDIA   | 
| MEDIA    | 
| PHYSICALCOLLECTION | 
| SEQUENCE   | 
| TAPEMEDIA   | 
| VIRTUALCOLLECTION | 
+--------------------+ 
6 rows in set (0.00 sec) 

而意外表MEDIA就有了用武之地定義(重命名PhysicalCollection當外鍵的目標改變語義):

CREATE TABLE `MEDIA` (
    `COLLECTION_ID` bigint(20) NOT NULL, 
    KEY `FK_MEDIA_COLLECTION_ID` (`COLLECTION_ID`), 
    CONSTRAINT `FK_MEDIA_COLLECTION_ID` FOREIGN KEY (`COLLECTION_ID`) REFERENCES PHYSICALCOLLECTION` (`ID`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 | 

質詢

  1. 是我expectiations是否正確? (創建4個表格,而不是5個)
  2. 有人可以確認這是EclipseLink中的錯誤嗎?
  3. 如果不是一個錯誤,你能指出我犯了什麼錯誤嗎?
+0

我有一個類似的模型和相同的問題。你是否設法解決它? – 2013-08-03 12:30:05

回答

1

TABLE_PER_CLASS不應該爲任何抽象類創建表,所以這是一個錯誤。很奇怪,你還沒有收藏一張桌子?你確定媒體是抽象的,你錯過重新編譯/部署你的代碼嗎?

我知道這個錯誤存在於EclipseLink 2.0中,但認爲之後它已經修復,所以你可能想試試最新版本,否則記錄一個錯誤。

一般來說,我不會推薦TABLE_PER_CLASS,特別是在這個模型中,你有很多realtionships。使用SINGLE_TABLE或JOINED繼承會好得多。

+0

是的,請放心,我多次檢查重新編譯和緩存問題;)。 – Chronos 2013-05-03 18:39:49

+0

顯然,MEDIA是因爲它定義了@JoinColumn(這沒有任何意義)而創建的,並且因爲它試圖引用一個抽象類,所以不能使用底層DB作爲外鍵約束;它因此錯誤地映射到一些具體的亞型(這幾乎是犯罪)。 – Chronos 2013-05-03 18:43:15

+0

與此同時,我發現有其他人有這個問題[http://www.verious.com/qa/jpa-one-to-many-using-inheritance/],顯然eclipselink目前(v2.4.0 )不提供此功能。 – Chronos 2013-05-03 18:46:12