2013-04-30 56 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