Mikro-ORM 中的多表继承和枚举实体

问题描述

我有以下实体:Quiz、Slide、TextSlide 和 SlideType。测验可以有多个不同类型的幻灯片,例如 TextSlide、QuestionSlide 等。为了简洁起见,我仅在本示例中包含了 TextSlide。 SlideType 表作为一种存储所有 Slide 类型的方式,如枚举,但以适当的 sql 方式存储,因此使用 INT id。表格如下所示:

CREATE TABLE QUIZ (
    id         INT AUTO_INCREMENT PRIMARY KEY,name       VARCHAR(255) NOT NULL,...
);
CREATE TABLE SLIDE (
    id         INT AUTO_INCREMENT,`index`    INT NOT NULL,quiz_id    INT NOT NULL,...
);
CREATE TABLE SLIDE_TEXT (
    slide_id INT          NOT NULL,text     VARCHAR(255) NOT NULL,CONSTRAINT SLIDE_TEXT_pk PRIMARY KEY (slide_id),CONSTRAINT SLIDE_TEXT_SLIDE_id_fk FOREIGN KEY (slide_id) REFERENCES SLIDE (id) ON UPDATE CASCADE ON DELETE CASCADE
);
CREATE TABLE SLIDE_TYPE (
    id          INT AUTO_INCREMENT,code        VARCHAR(32)  NOT NULL,name        VARCHAR(64)  NOT NULL,description VARCHAR(128) NULL,CONSTRAINT SLIDE_TYPE_pk PRIMARY KEY (id)
);

这使得 Slide 成为一个有点抽象的类,只有三个常用参数:id、index 和 quiz_id。像 TextSlide 和 QuestionSlide 这样的实现都有不同的字段,但都是从这个 Slide 实体扩展而来的。

我将如何使用 JPA 在 Java 中解决此问题,如下所示:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "SLIDE")
public abstract class Slide {
    @Id
    @GeneratedValue
    @Column
    private Integer id;

    // ...

    @OnetoOne
    @JoinColumn(name = "slide_type_id")
    private SlideType slideType;

    public Slide(Integer id,/*...*/ SlideType slideType) {
        this.id = id;
        this.slideType = slideType;
    }
}

// PersistableEnum is an interface to help with conversion.
@Entity
@Table(name = "SLIDE_TYPE")
public enum SlideType implements PersistableEnum<SlideType,Integer> {
    TEXT(1),QUESTION(2);

    @Id
    @GeneratedValue
    @Column(name = "id")
    private final Integer id;

    SlideType(Integer id) {
        this.id = id;
    }

    @Override
    public Integer getId() {
        return id;
    }
}
@Entity
@PrimaryKeyJoinColumn(name = "slide_id")
@Table(name = "SLIDE_TEXT")
public final class TextSlide extends Slide {
    @Column(nullable = false,length = 255)
    private String text;

    // ...

    public TextSlide(Integer index,/*...*/ String text) {
        super(index,SlideType.TEXT);
        this.text = text;
    }
}

但是,我似乎想不出使用 Mikro-ORM 来做到这一点的解决方案。有一些挑战:

  • 枚举不能用作实体
  • 使用 TextSlide 扩展 Slide 会导致 TextSlide 继承 Slide 的属性,而我实际上希望 TextSlide 是 Slide 实体的实现,其中某些字段属于 Slide (id,index,quiz_id,...) 而某些字段属于TextSlide (slide_id,text,...);我想使用一个通用超类 (Slide) 的原因是因为 Quiz 可以急切地获取所有实现,而且我不必担心类型,直到我稍后需要特定属性

有人可以指出我正确的方向吗?提前致谢。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)