两个(每类表) - 继承树之间的双向一对多关系

时间:2013-04-30 13:35:28

标签: jpa eclipselink one-to-many table-per-class

摘要

说,我有两个简单的@Entity继承树(一个抽象基类,每个树中有两个具体的实现类)的InheritanceType.TABLE_PER_CLASS;我需要一个使用@JoinColumn连接基类的双向@OneToMany关系。

这应该产生四个表,每个具体类一个,对吗? EclipseLink为其中一个抽象基类生成了第五个表,这对我来说没有意义。考虑这个例子(这不是一个真实的例子;它只是关于JPA):

示例

Collection是第一个继承树的抽象根和@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是Collection的具体实现:

@Entity
public class PhysicalCollection extends Collection {}

@Entity
public class VirtualCollection extends Collection {}

Media是第二个继承树的抽象根,是@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是Media的具体实现:

@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. 我的期望是否正确? (创建4个表,而不是5个)
  2. 有人可以确认这是EclipseLink中的错误吗?
  3. 如果不是错误,你能指出我犯错的地方吗?

1 个答案:

答案 0 :(得分:1)

TABLE_PER_CLASS不应该为任何抽象类创建表,因此这是一个错误。很奇怪你还没有收集一张桌子?你确定MEDIA是抽象的,你是否错过了重新编译/部署代码?

我知道EclipseLink 2.0中存在此错误,但认为之后已修复,因此您可能需要尝试最新版本,否则请记录错误。

一般情况下,我不推荐TABLE_PER_CLASS,特别是在这个你有很多实际情况的模型中。使用SINGLE_TABLE或JOINED继承会好得多。