2014-02-12 65 views
0

我有一個實體Item,它通過一個連接表與其他Items相關。但是,當持久化相關項目時,我需要插入「additionalField」的值。如何爲連接表指定其他插入信息?

我正在使用彈簧數據JPA(1.4.1)進行持久性抽象。 EclipseLink(2.5.0)是我的JPA提供程序。

@Entity 
public class Item { 

    // other fields and getters/setters omitted for clarity 

    @OneToMany 
    @JoinTable(name = "related_items_map", 
     joinColumns = @JoinColumn(name = "fk_item"), 
     inverseJoinColumns = @JoinColumn(name = "fk_related_item")) 
    private List<Item> relatedItems; 
} 

join table name = "related_items_map" with 
    columns = fk_item, fk_related_item, additionalField 

我的最終目標是要實現以下語義:

// obtain the items from service by id 
Item item = itemService.findOne(1); 
Item relatedItem = itemService.findOne(2); 

// add related item to item related list 
item.getRelatedItems().add(relatedItem); 

// save item using service 
itemService.save(item); 

今天生成的SQL看起來是正確的

INSERT INTO item (fk_item, fk_related_item) values (?, ?) => bind [1, 2] 

唯一的問題是,additionalField欄爲空。應該插入的值是在插入之前的運行時間計算的(基於特定的狀態)。

如何爲此操作定製插頁?我知道如何自定義特定的類,但不是映射。

==== ==== UPDATE

正如克里斯建議,我創建包裹 「JoinTable」

@Entity 
@Table("related_items_map") 
public class RelatedItem { 
    @Id 
    private String itemId; 

    @Id 
    private String relatedItemId; 

    // ... other stuff 
} 

@Entity 
public class Item { 

    // other fields and getters/setters omitted for clarity 

    @OneToMany 
    @JoinTable(name = "related_items_map", 
     joinColumns = @JoinColumn(name = "fk_item")) 
    private List<RelatedItem> relatedItems; 
} 

然而,的EclipseLink試圖做一個多重插入現在,當一個實體我做到以下幾點:

// obtain two items 
Item item = itemService.find(1); 
Item other = itemService.find(2); 

// create the joining 
RelatedItem relatedItem = new RelatedItem(); 
relatedItem.setItemId(item.getId()); 
relatedItem.setRelatedId(other.getId()); 

// add the relation to the list of relations 
item.getRelatedItems().add(relatedItem); 

// update the item. 
itemService.save(item); 

我得到一個鍵約束衝突,因爲它正在嘗試做兩個插件:

INSERT INTO related_items_map(fk_item, fk_related_item, ...) values (?, ?, ...) => bind [1, 2, ...] 

INSERT INTO related_items_map(fk_item, fk_related_item) values (?, ?) => bind [1 ,2] 

我假設的第一個插入,因爲它是創建實際的實體。我假設的第二個原因是Item類上的OneToMany關係。我如何省略第二次插入?

+0

如果字段值來自實體狀態的計算,爲什麼需要插入 - 當需要檢索該值時,是否可以使用該狀態? – Chris

回答

1

除非該字段是某種索引,或者您想使用映射並將該字段用作鍵或值,否則JPA只允許在實體內映射字段。

因此,爲了便於攜帶而不必進入提供者細節,您需要爲該關係表創建一個實體。這允許該字段用於查詢並像任何其他字段一樣訪問。

+0

我按照建議做了,但遇到了問題。由於評論部分不足,我更新了原始問題。 – predhme

+1

related_items_map表不再是連接表,而是實體表,應該像其他任何1:M關係一樣對待。如果您使用的是JPA 2.0,則您可能希望使用M:1返回指針作爲其ID的雙向1:M與RelatedItem。參見http://wiki.eclipse.org/EclipseLink/Examples/JPA/2.0/DerivedIdentifiers一個簡單的例子 – Chris

+0

「不再是一個連接表,而是一個實體的表」......啊,這是非常真實的。感謝我清楚地錯過的觀點。 – predhme

相關問題