2014-03-26 109 views
0

我把手放在一個非常古老的基於數據庫的舊應用程序(即MySQL)上,該應用程序有兩張用於映射發票的表格:我們稱之爲INVOICE_HEADER和INVOICE_ROWS。使用複合鍵連接兩個表

那麼,理想的情況顯然是在發票實體@Id Long id;和雙向@OneToMany + @ManyToOne關係,通過在INVOICE_ROWS表FK_HEADER外鍵映射。正常的JPA方法來映射這種類型的關係。

但是,該表(標題一)有四個(是,四個!)列作爲複合主鍵(年,數,t1,t2)以及行表。該應用程序正在使用這四列在兩個表格之間進行手動JOIN。 完全沒有外鍵約束。

不幸的是,模式根本不可改變。 我將如何編寫我的兩個JPA實體? 我認爲這是@IdClass(或@EmbeddedId?)的用例。

是否可以通過組合鍵映射@OneToMany關係? 你能幫我一些例子嗎?謝謝

回答

1

是的,這是可能的,應該不會有任何困難 - ORA JPA是基於設計靈活的解決方案。 JPA使用的ID甚至不必是數據庫中使用的PK;唯一的限制是它應該是唯一的。 JPA 2包含對派生ID的支持,這可能有所幫助,因爲我認爲INVOICE_ROWS的PK是INVOICE_HEADER FK和其他字段的組合。如果它有自己的序列,那麼它簡化了一下。

您可以選擇要使用的選項 - IdClass或將實體中的id類作爲EmbeddedId進行緩存。我的偏好通常是IdClass,因爲我不使用這個類。因此,一個簡單的例子是:

@Entity 
@IdClass(HeaderPK.class) 
class Header { 
    @Id 
    java.sql.Date year; 
    @Id 
    Integer number; 
    @Id 
    String t1; 
    @Id 
    String t2; 
    @OneToMany(mappedby="header") 
    List<Row> rows; 
} 

class HeaderPK { 
    java.sql.Date year; 
    Integer number; 
    String t1; 
    String t2; 
} 

@Entity 
@IdClass(RowPK.class) 
class Row { 
    @Id 
    String someField; 
    @Id 
    @ManyToOne 
    @JoinColumns({ 
     @JoinColumn(name="YEAR", referencedColumnName="YEAR"), 
     @JoinColumn(name="NUMBER", referencedColumnName="NUMBER"), 
     @JoinColumn(name="T1", referencedColumnName="T1"), 
     @JoinColumn(name="T2", referencedColumnName="T2"), 
    }) 
    Header header; 
} 

class RowPK { 
    String someField; 
    HeaderPK header; 
} 

每個JoinColumn註解的定義外重點領域和它們指向主鍵字段。 JPA有一個限制,外鍵必須轉到主鍵字段 - 我相信這是爲了允許實體緩存,因爲它們被緩存在主鍵上。如果需要,許多提供商都有解決此限制的方法

如果您的Row實體具有單個主鍵,則可以使用RowPk類來實現。