跳轉到內容

Java 持久化/ElementCollection

來自 Wikibooks,開放世界中的開放書籍

ElementCollection

[編輯 | 編輯原始碼]

JPA 2.0 定義了 ElementCollection 對映。它旨在處理幾種非標準關係對映。ElementCollection 可用於定義與 Embeddable 物件的 一對多 關係,或 Basic 值(例如 String 集合)。ElementCollection 也可以與 Map 結合使用來定義關係,其中鍵可以是任何型別的物件,而值是 Embeddable 物件或 Basic 值。

在 JPA 中,ElementCollection 關係透過 @ElementCollection 註解或 <element-collection> 元素定義。

ElementCollection 值始終儲存在單獨的表中。該表透過 @CollectionTable 註解或 <collection-table> 元素定義。CollectionTable 定義了表的 name@JoinColumn@JoinColumns (如果使用複合主鍵)。

嵌入式集合

[編輯 | 編輯原始碼]

ElementCollection 對映可用於定義 Embeddable 物件的集合。這不是 Embeddable 物件的典型用法,因為這些物件不會嵌入到源物件的表中,而是儲存在單獨的集合表中。這類似於 OneToMany,只是目標物件是 Embeddable 而不是 Entity。這允許輕鬆定義簡單物件的集合,而無需要求簡單物件定義 IdManyToOne 逆對映。ElementCollection 還可以覆蓋其集合的對映或表,因此您可以讓多個實體引用同一個 Embeddable 類,但每個實體將它們相關的物件儲存在單獨的表中。

使用 ElementCollection 而不是 OneToMany 的侷限性在於,目標物件無法獨立於其父物件進行查詢、持久化、合併。它們嚴格來說是私有擁有的(依賴)物件,與 Embedded 對映相同。ElementCollection 上沒有 cascade 選項,目標物件始終與其父物件一起持久化、合併、刪除。ElementCollection 仍然可以使用 fetch 型別,並且預設情況下為 LAZY,與其他集合對映相同。

ElementCollection 關係資料庫示例

[編輯 | 編輯原始碼]

EMPLOYEE(表)

EMP_ID F_NAME L_NAME SALARY
1 Bob Way 50000
2 Joe Smith 35000

PHONE(表)

OWNER_ID TYPE AREA_CODE P_NUMBER
1 home 613 792-0001
1 work 613 494-1234
2 work 416 892-0005

ElementCollection 關係註解示例

[編輯 | 編輯原始碼]
@Entity
public class Employee {
  @Id
  @Column(name="EMP_ID")
  private long id;
  ...
  @ElementCollection
  @CollectionTable(
        name="PHONE",
        joinColumns=@JoinColumn(name="OWNER_ID")
  )
  private List<Phone> phones;
  ...
}
@Embeddable
public class Phone {
  private String type;
  private String areaCode;
  @Column(name="P_NUMBER")
  private String number;
  ...
}

ElementCollection 關係 XML 示例

[編輯 | 編輯原始碼]
<entity name="Employee" class="org.acme.Employee" access="FIELD">
    <attributes>
        <id name="id">
            <column name="EMP_ID"/>
        </id>
        <element-collection name="phones">
            <collection-table name="PHONE">
                <join-column name="OWNER_ID"/>
            </collection-table>
        </element-collection>
    </attributes>
</entity>
<embeddable name="Phone" class="org.acme.Phone" access="FIELD">
    <attributes>
        <basic name="number">
            <column name="P_NUMBER"/>
        </basic>
    </attributes>
</embeddable>

基本集合

[編輯 | 編輯原始碼]

ElementCollection 對映可用於定義 Basic 物件的集合。Basic 值儲存在單獨的集合表中。這類似於 OneToMany,只是目標是 Basic 值而不是 Entity。這允許輕鬆定義簡單值的集合,而無需為該值定義類。

ElementCollection 上沒有 cascade 選項,目標物件始終與其父物件一起持久化、合併、刪除。ElementCollection 仍然可以使用 fetch 型別,並且預設情況下為 LAZY,與其他集合對映相同。

ElementCollection 關係到基本值資料庫示例

[編輯 | 編輯原始碼]

EMPLOYEE(表)

EMP_ID F_NAME L_NAME SALARY
1 Bob Way 50000
2 Joe Smith 35000

PHONE(表)

OWNER_ID PHONE_NUMBER
1 613-792-0001
1 613-494-1234
2 416-892-0005

ElementCollection 關係到基本值註解示例

[編輯 | 編輯原始碼]
@Entity
public class Employee {
  @Id
  @Column(name="EMP_ID")
  private long id;
  ...
  @ElementCollection
  @CollectionTable(
        name="PHONE",
        joinColumns=@JoinColumn(name="OWNER_ID")
  )
  @Column(name="PHONE_NUMBER")
  private List<String> phones;
  ...
}

ElementCollection 關係到基本值 XML 示例

[編輯 | 編輯原始碼]
<entity name="Employee" class="org.acme.Employee" access="FIELD">
    <attributes>
        <id name="id">
            <column name="EMP_ID" />
        </id>
        <element-collection name="phones" target-class="java.lang.String">
            <column name="PHONE_NUMBER" />
            <collection-table name="PHONE">
                <join-column name="OWNER_ID" />
            </collection-table>
        </element-collection>
    </attributes>
</entity>

另請參見

[編輯 | 編輯原始碼]

常見問題

[編輯 | 編輯原始碼]
CollectionTable 中的主鍵
[編輯 | 編輯原始碼]
JPA 2.0 規範沒有提供定義 EmbeddableId 的方法。但是,為了刪除或更新 ElementCollection 對映的元素,通常需要一些唯一的。否則,JPA 提供者將需要在每次更新時從 EntityCollectionTable 中刪除所有內容,然後再插入值。因此,JPA 提供者很可能會假設 Embeddable 中所有欄位的組合與外部索引鍵(JoinColumn(s))組合是唯一的。然而,如果 Embeddable 很大或很複雜,這可能效率低下或不可行。
一些 JPA 提供者可能允許在 Embeddable 中指定 Id 來解決此問題。請注意,在這種情況下,Id 只需要在集合中是唯一的,而不是在表中是唯一的,因為外部索引鍵包含在內。一些 JPA 提供者也可能允許使用 CollectionTable 上的 unique 選項來實現這一點。否則,如果 Embeddable 很複雜,您可能需要將其改為 Entity,並使用 OneToMany 代替。
華夏公益教科書