摘要
说,我有两个简单的@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 |
问题
答案 0 :(得分:1)
TABLE_PER_CLASS不应该为任何抽象类创建表,因此这是一个错误。很奇怪你还没有收集一张桌子?你确定MEDIA是抽象的,你是否错过了重新编译/部署代码?
我知道EclipseLink 2.0中存在此错误,但认为之后已修复,因此您可能需要尝试最新版本,否则请记录错误。
一般情况下,我不推荐TABLE_PER_CLASS,特别是在这个你有很多实际情况的模型中。使用SINGLE_TABLE或JOINED继承会好得多。