1

スプリングバッチとJPA(休止状態で提供)を使用します。

次の手順があります。

  • DB(クライアントエンティティ)からすべてのクライアントを読み取ります
  • サードパーティからのデータでそれらを強化します。ItemProcessorはサードパーティのデータソースに移動し、クライアントエンティティ自体(そのフィールド)に格納されているデータをフェッチしますが、さまざまなエンティティ(ClientSale)として格納されているデータをさらに取得し、クライアントには次のようにマップされるListのプロパティがあります。 ManyToOne。
  • 変更されたエンティティ(Client)と新しいエンティティ(ClientSale)はDBに保存する必要があります。

リーダーの部分は単純明快で、ライターにはJPAItemWriterを使用しました。処理段階で、フィールドを更新し、新しいフィールドを作成してクライアントのリストに追加し、クライアントを返すことを試みました。ライターが参照されるオブジェクトとクライアント自体の両方をDBに書き込むことを期待しています。

代わりに、ID#123213213のClientSaleがDBに存在しないというエラーが発生しました。

これを克服するにはどうすればよいですか?プロセッサ(クライアント+すべてのClientSale)からオブジェクト(さまざまなタイプ)のリストを返す必要がありますか?JPAItemWriterはオブジェクトのリストを処理できますか?これに関するもう1つの問題は、ClientSaleエンティティをリストに追加して休止状態にする代わりに、ClientSaleエンティティのclient_idを手動で更新して、それらと誰がどこを指しているのかを理解する必要があることです。

ここでのベストプラクティスは何ですか?

ありがとう!

4

2 に答える 2

1

OK ..これが、すべてに基づいて最後に行ったことです。アイテムとしてリストを受け取ることができるMultiEntityItemWriterを作成しました(その場合、リストを開き、委任されたItemWriterにすべての要素を書き込みます。

コード:

public class MultiEntityItemWriter implements ItemWriter<Object>{

private ItemWriter<Object> delegate;

@Override
public void write(List<? extends Object> items) throws Exception {
    List<Object> toWrite = new ArrayList<>();

    for (Object item : items) {
        if (item instanceof Collection<?>) {
            toWrite.addAll((Collection<?>)item);
        } else {
            toWrite.add(item);
        }
    }
    delegate.write(toWrite);
}


public ItemWriter<Object> getDelegate() {
    return delegate;
}

public void setDelegate(ItemWriter<Object> delegate) {
    this.delegate = delegate;
}

}

これで、ItemProcessorは、書き込まれるすべてのエンティティを含むリストを出力できるようになりました。DBにコミットするエンティティが他にもあることを理解するために、JPAに依存する必要はありません。

それが役に立てば幸い...

于 2012-10-14T15:52:42.803 に答える
0

あなたは1つのステップで複数のステップに対応しようとしていると思います。方法を見つけて、仕事を1つではなく2つのステップのプロセスとして定義してみてください。

    <batch:job id="MyJob" incrementer="incrementer" job-repository="jobRepository">
     <batch:step id="step1" next="step2">
       <tasklet >
          <chunk reader="reader1" 
                     writer="writer1" 
                     processor="processor1" 
                     commit-interval="10" />
       </tasklet>
     </batch:step>
     <batch:step id="step2">
       <tasklet >
          <chunk reader="reader2" 
                     writer="writer2" 
                     processor="processor2" 
                     commit-interval="10" />
       </tasklet>
     </batch:step>
    </batch:job>

必要に応じて、最適なパフォーマンスを得るために適切なキャッシュを使用してください。

編集:

entityManager/sessionアイテムライターでは、最初のデータソースを使用していることを確認してください。またmerge、の代わりにあなたの敵を永続させるために使用しますpersist

于 2012-10-14T07:30:25.867 に答える