2010-12-10 93 views
2

我在更新鏈接到其他實體的實體屬性時在eclipselink中批量編寫時遇到問題。JPA/Eclipselink ManyToOne關係更改上性能不佳的批量更新實體

我有一個與卡實體有@ManyToOne關係的持卡人實體。

@Entity 
@Table(name = "...") 
@NamedQueries({...}) 
public class Cardholder implements Serializable { 
    ... 
    @JoinColumn(name = "card_number", referencedColumnName = "...") 
    @ManyToOne(fetch=FetchType.LAZY) 
    private Card card; 
} 

與@OneToMany關係的卡持卡人

@Entity 
@Table(name = "cms_card") 
@NamedQueries({...}) 
public class Card implements Serializable { 
    @OneToMany(mappedBy = "card") 
    private List<Cardholder> cardholderList; 
} 

我已經有孩子的名單(持續持卡人)。現在我想添加一些卡給他們, 所以: // cardholderList是一個託管實體列表。

for (Cardholder cardholder : cardholderList) { 
    Card newCard = new Card(); 
    ... 
    cardholder.setCard(newCard); 
    List<Cardholder> cardCardholders = new ArrayList<Cardholder>(); 
    cardCardholders.add(cardholder); 
    newCard.setCardholderList(cardCardholders); 
    cardsToBePersisted.add(newCard); 
    ++i; 
} 

我配置了我的Persistence.xml以使用批處理寫入,但對於-15000列表更新,性能非常低。現在,當我檢查到生成的SQL,我發現的EclipseLink爲一個查詢創建一個批處理,其狀如:

FINER: Begin batch statements 
FINE: INSERT INTO cms_card (card_number, status, chip_serial_number, dwh_status, valid_until, card_holder_id, file_perso_history_id, feedback_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?) 
FINE:   bind => [9030002005890011, ACTIVE, null, false, 2015-12-10, null, 241, null] 
FINER: End Batch Statements 
FINER: Begin batch statements 
FINE: UPDATE cms_cardholder SET card_number = ? WHERE (id = ?) 
FINE:   bind => [9030002005890011, 176075] 
FINER: End Batch Statements 
FINER: Begin batch statements 
FINE: INSERT INTO cms_card (card_number, status, chip_serial_number, dwh_status, valid_until, card_holder_id, file_perso_history_id, feedback_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?) 
FINE:   bind => [9030002005889908, ACTIVE, null, false, 2015-12-10, null, 241, null] 
FINER: End Batch Statements 

我想這是因爲我設置一個新的parent屬性(卡)到現有的兒童。

我也嘗試玩顛倒親子關係(持卡人 - >卡而不是卡 - >持卡人)。 批量插入是正確的後,我扭轉了在實體和數據庫中的關係,但Eclipselink仍然會查詢數據庫(選擇* cardcard.id =?卡),所以對於15000條記錄我有15000選擇語句。比上面好,但仍然非常慢。

我在設置批量文件時是否有任何錯誤? 非常感謝。

+0

你可以發佈EntityManager代碼嗎?您是否在任何時候發佈em.flush()? – 2010-12-13 16:10:58

回答

0

林真的不知道你的問題的原因,但我建議這樣做:

如果我有一個一對多和多對一的情況,而且涉及大量收集的數據,我會盡量避免使用集合添加細節[s],因爲它可能觸發在不需要時填充集合,這可能是性能問題的根源。

一個簡單的例子,這將有助於說明我的意思: 考慮2個實體的球隊和球員的, 一支球隊擁有球員名單(一對多) 一個玩家團隊(多對一)

每當我想添加一個新玩家,我會這樣做:

Team team = getTeamFromDbUsingEntityManager(teamId); Player player = new Player(); ... player.setTeam(team); entityManager.persist(player);

請注意,它does not做team.addPlayer(player);這意味着,你不會「觸摸」收藏。

1

卡和持卡人的所有關係是什麼?

您似乎在兩個類之間有一個循環,所以EclipseLink必須發出更新來解決循環。

您的Card中有card_holder_id,CardHolder中有card_number?爲什麼你在兩個表中都有foriegn鍵?如果你修復你的循環,那麼插入可以分組,並允許最佳的配料。

不知道你在做什麼來獲得選擇?這些是他們注意到的新對象?還是你在更新?