加入了没有鉴别列的继承

时间:2015-07-20 18:05:59

标签: jpa inheritance

我是这些遗留表(在Oracle数据库中):

CREATE TABLE "SPL_OWN"."SL_DOCUMENTO" ( 
    "ID_DOCUMENTO"     NUMBER(20,0) NOT NULL ENABLE, -- Primary Key
    ...
    "ID_PARECER_GERAL" NUMBER(20,0), -- Foreign Key
    "ID_PROPOSITURA"   NUMBER(20,0), -- Foreign Key
    ...
);

CREATE TABLE "SPL_OWN"."SL_PARECER_GERAL" ( 
    "SL_PARECER_GERAL" NUMBER(20,0) NOT NULL ENABLE, -- Primary Key
    ...
);

CREATE TABLE "SPL_OWN"."SL_PROPOSITURA" (   
    "ID_PROPOSITURA"   NUMBER(20,0) NOT NULL ENABLE, -- Primary Key
    ...
);

这里的特殊性是,SL_PARECER_GERAL.SL_PARECER_GERAL和SL_PROPOSITURA.ID_PROPOSITURA值实际上等于SL_DOCUMENTO.ID_DOCUMENTO。实际上,SL_PARECER_GERAL和SL_PROPOSITURA可以被认为是SL_DOCUMENTO子类(在这种情况下还有其他表,我使用这两个作为示例)。在理想情况下,我应该使用inheritance类型JOINED。但是,没有discriminator column

要确定SL_DOCUMENTO是否为SL_PROPOSITURA,应填写SL_DOCUMENTO.ID_PROPOSITURA,而SL_DOCUMENTO.ID_PARECER_GERAL应为NULL。另一方面,如果填充SL_DOCUMENTO.ID_PARECER_GERAL并且SL_DOCUMENTO.ID_PROPOSITURA是NULL,则SL_DOCUMENTO是SL_PARECER_GERAL。

在我的映射中,我没有使用继承策略。

@Entity
@Table(name = "SL_DOCUMENTO")
public class DocumentoORM {

    @Id
    @Column(name = "ID_DOCUMENTO")
    @SequenceGenerator(name = "SEQ_SL_DOCUMENTO", sequenceName = "SEQ_SL_DOCUMENTO")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_SL_DOCUMENTO")
    private Long id;

    @OneToOne(mappedBy = "documento", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_PARECER_GERAL", updatable = false)
    private ParecerGeralORM parecerGeral;

    @OneToOne(mappedBy = "documento", cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
    @JoinColumn(name = "ID_PROPOSITURA", updatable = false)
    private ProposituraORM propositura;

}

@MappedSuperclass
public abstract class BaseORM extends AbstractORM {

    @Id
    private Long id;

}

@Entity
@Table(name = "SL_PROPOSITURA")
@AttributeOverrides({ @AttributeOverride(name = "id", column = @Column(name = "ID_PROPOSITURA")) })
public class ProposituraORM extends BaseORM {

    @MapsId
    @OneToOne(optional = false)
    @JoinColumn(name = "ID_PROPOSITURA", nullable = false)
    private DocumentoORM documento;

    public ProposituraORM() {
    }

    public ProposituraORM(DocumentoORM documento) {
        super();
        this.documento = documento;
        this.documento.setPropositura(this);
    }

    // Getter & Setters

}

@Entity
@Table(name = "SL_PROCESSO")
@AttributeOverrides({ @AttributeOverride(name = "id", column = @Column(name = "ID_PROCESSO")) })
public class ProcessoORM extends BaseORM {

    @MapsId
    @OneToOne
    @JoinColumn(name = "ID_PROCESSO")
    private DocumentoORM documento;

    public ProcessoORM() {
    }

    public ProcessoORM(DocumentoORM documento) {
        this.setDocumento(documento);
        documento.setProcesso(this);
    }

    // Getter & Setters

}

当插入ProposituraORM时,JPA会在ProposituraORM实例之前保留DocumentoORM。但是,尽管SL_PROPOSITURA.ID_PROPOSITURA具有与SL_DOCUMENTO.ID_DOCUMENTO相同的值,但列SL_DOCUMENTO.ID_PROPOSITURA仍为NULL。为了解决这个问题,我应该创建一个解决方法,我将其填充到#34;手动",朝向本机SQL。显然,同样的机制适用于ProcessoORM。

因此,我想知道是否有更好的替代方法来使用没有鉴别器列的连接继承。在某些地方,我找到了对@SecondaryTable@PrimaryKeyJoinColumn注释的引用。在这里,我在StackOverflow中看到了一些相关的问题,但我无法将它们应用到我的情况中。

谢谢,

Rafael Afonso

1 个答案:

答案 0 :(得分:0)

实际上,你几乎就在那里。

TABLE_PER_CLASS继承类型可能会这样做。换句话说,您的BaseORM类应该有

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class BaseORM extends AbstractORM {

您甚至不需要使用@SecondaryTable,因为DocumentoORM已与@OneToOne相关联。

要确保正确填写所有ID,您需要在关联的两个侧定义参考。换句话说,如果您有两个对象documentopropositura,那么在保存之前,您需要执行以下操作:

documento.setPropositura(propositura);
propositura.setDocumento(documento);