2015-07-20 46 views
0

我這些舊錶(在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的子類(在這種情況下還有其他的表格,我用這兩個作爲例子)。在理想的情況下,我應該使用類型爲JOINEDinheritance。但是,沒有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使得該DocumentoORM的ProposituraORM實例之前被持久。但是,雖然SL_PROPOSITURA.ID_PROPOSITURA與SL_DOCUMENTO.ID_DOCUMENTO具有相同的值,但SL_DOCUMENTO.ID_PROPOSITURA列仍爲NULL。爲了解決這個問題,我應該創建一個解決方法,將其「手動」填充到原生SQL中。顯然,ProcessoORM的機制是一樣的。

因此,我想知道是否有更好的選擇使用加入繼承沒有鑑別器列。在一些地方,我發現對@SecondaryTable@PrimaryKeyJoinColumn註釋的引用。在這裏,在StackOverflow中我看到了一些相關的問題,但我無法將它們應用於我的情況。

感謝,

拉斐爾·阿豐索

+0

爲什麼你不能使用'@ SecondaryTable'?這似乎很適合你的情況。這樣你就可以將'ProposituraORM'和'ProcessoORM'類定義爲'@SecondaryTable'。然後,您可以將「DocumentoORM」嵌入並嵌入到兩個類中。 – DuncanKinnear

+0

@DuncanKinnear:你知道一個具體的例子嗎?可能不會使用繼承註釋。 –

回答

0

其實,你幾乎沒有。

TABLE_PER_CLASS繼承類型可能會這樣做。換句話說,你的BaseORM類應該有

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

你甚至不需要使用已經與@OneToOne相關的@SecondaryTableDocumentoORM

爲了確保所有ID都能正確填寫,您需要定義的參考文件,這兩個兩邊都是關聯的。所以,換句話說,如果你有兩個對象documentopropositura然後保存之前,你需要做到以下幾點:

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