2010-12-10 33 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; 
} 

と私はすでに子供のリスト(カード会員を永続化)を持っているカード保有者

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

と@OneToMany関係にカード。今度はカードを に追加します: // 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; 
} 

Iは、バッチ書き込みを使用するために私のpersistence.xmlを構成しますが、パフォーマンスは+ -15000リストの更新のために恐ろしく遅いです。

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 

私は、既存の子供たちに新しい親プロパティ(カード)を設定しているため、これがあると思う:私は、生成されたSQLにチェックしたときに今、私はEclipseLinkは、そのような、1つのクエリの1つのバッチを作成していることがわかりました。

私は親子関係(カード - >カード所有者の代わりにカード保有者 - >カード)を逆にしてプレイしようとします。 エンティティとデータベースの関係を逆にしてもバッチインサートは正しいですが、Eclipselinkはデータベース(SELECT * from cardholder.id =?)を照会するので、15000レコードの場合は15000 select文が得られます。上記より優れていますが、依然として非常に遅いです。

バッチ書込みの設定に間違いがありますか? ありがとうございます。

+0

EntityManagerコードも投稿できますか?いつでもem.flush()を発行していますか? –

答えて

0

イム問題の原因について本当にわからないが、私はこれを行うことをお勧め:

私はoneToManyとmanyToOne状況を持っている、そしてそれは、収集データの多くを必要とする場合、私はコレクションの使用を避けますディテール[s]を追加する必要があります。これは、パフォーマンスの問題の原因になる可能性がある場合にコレクションが必要ないときにコレクションを投入する可能性があるためです。私は何を意味するのか説明するのに役立ちます

簡単な例: チームと選手の2つのエンティティを考えてみましょう、 Aチームは選手のリスト(多くの1つ)を持っている Aプレーヤーは、(1への多くの)チーム

を持っています

新しいプレーヤーを追加したいときはいつでも:

チームチーム= getTeamFromDbUsingEntityManager(teamId); プレーヤープレーヤー=新しいプレーヤー(); ... player.setTeam(team); entityManager.persist(player);

これは、team.addPlayer(player)とは異なります。つまり、コレクションに「触れていない」ということです。

1

カードとカード会員の関係はすべて何ですか?

2つのクラスの間にサイクルがあるようですので、EclipseLinkはサイクルを解決するために更新を発行する必要があります。

カードにcard_holder_idがあり、CardHolderにcard_numberがありますか?なぜあなたは両方のテーブルに他のキーと同じキーを持っていますか?サイクルを修正すると、インサートをグループ化して最適なバッチ処理を行うことができます。

選択を行うために何をしているのかよくわからないですか?これらは新しいものですか?それともあなたも更新していますか?

関連する問題