2016-07-09 3 views
1

データを更新するためにJPAリポジトリに依存するスプリングバッチItemWriterに問題があります。JPAリポジトリを使用したSpringバッチの問題を永続化します。

ここにある:ここでは

@Component 
public class MessagesDigestMailerItemWriter implements ItemWriter<UserAccount> { 

    private static final Logger log = LoggerFactory.getLogger(MessagesDigestMailerItemWriter.class); 

    @Autowired 
    private MessageRepository messageRepository; 

    @Autowired 
    private MailerService mailerService; 

    @Override 
    public void write(List<? extends UserAccount> userAccounts) throws Exception { 
     log.info("Mailing messages digests and updating messages notification statuses"); 

     for (UserAccount userAccount : userAccounts) { 
      if (userAccount.isEmailNotification()) { 
       mailerService.mailMessagesDigest(userAccount); 
      } 
      for (Message message : userAccount.getReceivedMessages()) { 
       message.setNotificationSent(true); 
       messageRepository.save(message);//NOT SAVING!! 
      } 
     } 
    } 
} 

は私Step設定です:ここでは、完全性期すため

@Configuration 
public class MailStepConfiguration { 

    @Autowired 
    private StepBuilderFactory stepBuilderFactory; 

    @Autowired 
    private EntityManagerFactory entityManagerFactory; 

    @Autowired 
    private MessagesDigestMailerItemWriter itemWriter; 

    @Bean 
    public Step messagesDigestMailingStep() { 
     return stepBuilderFactory.get("messagesDigestMailingStep")// 
       .<UserAccount, UserAccount> chunk(1)// 
       .reader(jpaPagingItemReader(entityManagerFactory))// 
       .writer(itemWriter)// 
       .build(); 
    } 

    @Bean(destroyMethod = "") 
    @StepScope 
    public static ItemReader<UserAccount> jpaPagingItemReader(EntityManagerFactory entityManagerFactory) { 
     final JpaPagingItemReader<UserAccount> reader = new JpaPagingItemReader<>(); 
     reader.setEntityManagerFactory(entityManagerFactory); 
     reader.setQueryString("SELECT ua FROM UserAccount ua JOIN FETCH ua.receivedMessages msg WHERE msg.notificationSent = false AND msg.messageRead = false"); 
     return reader; 
    } 

} 

私の春のブート構成されています

@Configuration 
@EnableBatchProcessing 
@EnableAutoConfiguration 
@ComponentScan("com.bignibou.batch.configuration") 
public class Batch { 
    public static void main(String[] args) { 
     System.exit(SpringApplication.exit(new SpringApplicationBuilder(Batch.class).web(false).run(args))); 
    } 
} 

と私のデータソース設定:

@Configuration 
@EnableJpaRepositories({ "com.bignibou.repository" }) 
@EntityScan("com.bignibou.domain") 
public class DatasourceConfiguration { 

    @Bean 
    @ConfigurationProperties("spring.datasource.batch") 
    public DataSource batchDatasource() { 
     return DataSourceBuilder.create().build(); 
    } 

    @Bean 
    @Primary 
    @ConfigurationProperties("spring.datasource.application") 
    public DataSource applicationDatasource() { 
     return DataSourceBuilder.create().build(); 
    } 
} 

私は、実行フローがItemWriterのwriteメソッドに入るとmessageRepository.save(message);が実行されますんが、データが更新されないことに気づきました。

編集 ...私はそれが取引の問題である疑いがあるが、私はこの問題を解決する方法がわからないです:私は2つののPostgresデータベースを持っていることを言及するのを忘れてしまった:

  1. ジョブ・リポジトリー・データ用
  2. アプリケーション・データ用にもう1つ。

データがジョブリポジトリデータベースに書き込まれていることを確認できます。問題はアプリケーションデータにあります。私は2つのPGデータベースを持っていることを念頭に置かれた分散トランザクションを使用する必要がありますか?

+0

唯一の解決策は分散txマネージャを使用することです。私はここに別の質問を開いた:http://stackoverflow.com/questions/38323207 – balteo

+0

こんにちは@balteo、 解決策はありますか?私は正確な問題に直面しています。あなたが解決策を分かち合うことができれば素晴らしいだろう。 –

+0

こんにちは@balteo、この問題の解決策を見つけましたか?私はあなたと同様の方法でリポジトリを作っていますが、同様の不満足な結果を得ています:-( –

答えて

1

メインクラスには@EnableTransactionManagementが必要です。私はSpring Bootがトランザクションマネージャを作成すると信じていますが、デフォルトを上書きしたい場合はwant to configure it explicitlyです。

スプリングバッチよりもAPIs for changing transaction attributesを提供します。

+0

あなたの答えはおかげで '@ EnableTransactionManagement'を無駄にしようとしました。 Springバッチでの使用は推奨されていません。 – balteo

0

が、私はここに、このために問題を開いた:

@Configuration 
public class JpaConfig { 

    private final DataSource dataSource; 

    @Autowired 
    public JpaConfig(@Qualifier("dataSource") DataSource dataSource) { 
     this.dataSource = dataSource; 
    } 

    @Bean 
    @Primary 
    public JpaTransactionManager jpaTransactionManager() { 
     final JpaTransactionManager transactionManager = new JpaTransactionManager(); 
     transactionManager.setDataSource(dataSource); 
     return transactionManager; 
    } 

} 

そして、トランザクションのautowiredインスタンスを使用して:原則として

https://jira.spring.io/browse/BATCH-2642

を、どのような私たちを助けたことはそうのような主要なトランザクションマネージャを設定することでした管理者が手順を設定するときは、次のようにします。

@Autowired 
private PlatformTransactionManager transactionManager; 

private TaskletStep buildTaskletStep() { 
     return stepBuilderFactory.get("SendCampaignStep") 
        .<UserAccount, UserAccount>chunk(pushServiceConfiguration.getCampaignBatchSize()) 
        .reader(userAccountItemReader) 
        .processor(userAccountItemProcessor) 
        .writer(userAccountItemWriter) 
        .transactionManager(transactionManager) 
        .build(); 
    } 
} 

データが正しく保存されるようになりましたが、まだ完全には得られない魔法があります...

関連する問題