概要
InheritanceType.TABLE_PER_CLASS; の 2 つの単純な @Entity 継承ツリー (各ツリーに 2 つの具象実装クラスを持つ 1 つの抽象基本クラス) があるとします。@JoinColumn を使用して基本クラスを接続する双方向の @OneToMany リレーションが必要です。
これにより、具体的なクラスごとに 1 つずつ、合計4 つのテーブルが生成されるはずです。EclipseLink は、意味をなさない抽象基本クラスの 1 つの 5 番目のテーブルを生成します。次の例を考えてみましょう (これは実際の例ではなく、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 は、2 番目の継承ツリーの抽象ルートであり、@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 {}
結果
前述したように、EclipseLink はこれから5 つのテーブルを生成します (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 |
質問
- 私の期待は正しいですか?(5 つではなく 4 つのテーブルを作成します)
- これがEclipseLinkのバグであることを誰かが確認できますか?
- バグでなければ、どこが間違っているのか指摘してもらえますか?