2017-06-01 41 views
0

我无法使用我的子表(TBL_PAYMENT_DETAILS)与Spring批次添加外键关系。关于亲子依赖关系的春季批次撰稿人

我收到此错误:Not-null property references a transient value在这条线:paymentDetailsTblRepository.save(payDetails);

我试图与这两个作家的调用替换compositePaymentItemWriterpaymentRepoItemWriterpaymentInstallmentItemWriter思维paymentRepoItemWriter将首先坚持父,所以我可以把它引用到我的孩子桌子。但同样的问题。

我在想如果它一定是因为我打电话paymentDetailsTblRepository.save(payDetails)和父母还没有持续,直到StepJob完成?

父表:

@Entity 
@Table(name = "TBL_PAYMENT") 
public class PaymentTbl { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "ID") 
    private Long id; 

    @Column(name = "BILL_PERIOD", nullable = false) 
    private LocalDateTime billPeriod; 

    @Column(name = "INVOICE_NO", nullable = false) 
    private String invoiceNum; 

    @Column(name = "AMOUNT") 
    private BigDecimal amount; 
} 

子表:

@Entity 
@Table(name = "TBL_PAYMENT_DETAILS") 
public class PaymentDetailsTbl { 

    @EmbeddedId 
    private PaymentDetailsId id; // billPeriod and invoiceNum and paymentNum 

    @Column(name = "INSTALLMENT_AMOUNT") 
    private BigDecimal installmentAmount; 

    @ManyToOne 
    @JoinColumn(name = "PAY_ID", referencedColumnName = "ID", 
      insertable = false, updatable = false) 
    private PaymentTbl paymentTbl; 

这是我的步骤:

// CalculatePaymentProcessor skips some rows (return null) 
@Bean 
protected Step calculatePaymentStep(
     @Autowired final CalculatePaymentReader calculatePaymentReader, 
     @Autowired final CalculatePaymentProcessor calculatePaymentProcessor, 
     @Autowired final RepositoryItemWriter<PaymentTbl> paymentRepoItemWriter, 
     @Autowired final ItemWriter<PaymentTbl> paymentInstallmentItemWriter, 
     @Autowired final CompositeItemWriter<PaymentTbl> compositePaymentItemWriter) throws Exception { 

    return stepBuilderFactory.get("calculatePaymentStep") 
      .allowStartIfComplete(true) 
      .chunk(20000) 
      .reader(calculatePaymentReader) 
      .processor(calculatePaymentProcessor) 
      //.writer(compositePaymentItemWriter) 
      .writer(paymentRepoItemWriter) 
      .writer(paymentInstallmentItemWriter) 
      .build(); 
} 

我的作家:

@Bean 
public RepositoryItemWriter<PaymentTbl> paymentRepoItemWriter() throws Exception { 
    RepositoryItemWriter<PaymentTbl> writer = new RepositoryItemWriter<>(); 
    writer.setMethodName("save"); 
    writer.setRepository(paymentTblRepository); 
    writer.afterPropertiesSet(); 
    return writer; 
} 

@Bean 
public ItemWriter<PaymentTbl> paymentInstallmentItemWriter() { 
    return payList -> { 

     for (PaymentTbl p : payList) { 
      if (...) { 
       IntStream.range(1, 4).forEach(num -> { 
        PaymentDetailsTbl payDetails = new PaymentDetailsTbl(); 
        payDetails.setInstallmentAmount(...); 
        payDetails.setId(new PaymentDetailsId(...); 
        payDetails.setPaymentTbl(p); 
        paymentDetailsTblRepository.save(payDetails); 
       }); 
      } 
     } 
    }; 
} 

@Bean 
public CompositeItemWriter<PaymentTbl> compositePaymentItemWriter() throws Exception { 
    CompositeItemWriter<PaymentTbl> writer = new CompositeItemWriter(); 
    writer.setDelegates(Arrays.asList(paymentRepoItemWriter(), paymentInstallmentItemWriter())); 
    return writer; 
} 

回答

0

您多次拨打writer(ItemWriter writer)。每个人都将取代以前的作品,而不是添加到作家名单中。相反,您需要创建一个单独的CompositeItemWriter,其中列出了您的委托,然后将该复合写入器注册为步骤构建器的唯一编写者。

@Bean 
protected Step calculatePaymentStep(
     @Autowired final CalculatePaymentReader calculatePaymentReader, 
     @Autowired final CalculatePaymentProcessor calculatePaymentProcessor, 
     @Autowired final ItemWriter<PaymentTbl> compositeItemWriter 
) throws Exception { 

    return stepBuilderFactory.get("calculatePaymentStep") 
      .allowStartIfComplete(true) 
      .chunk(20000) 
      .reader(calculatePaymentReader) 
      .processor(calculatePaymentProcessor) 
      .writer(compositeItemWriter) 
      .build(); 
} 

@Bean 
protected ItemWriter<PaymentTbl> compositeItemWriter(
     @Autowired final RepositoryItemWriter<PaymentTbl> paymentRepoItemWriter, 
     @Autowired final ItemWriter<PaymentTbl> paymentInstallmentItemWriter) { 

    CompositeItemWriter<PaymentTbl> writer = new CompositeItemWriter<>(); 
    List<ItemWriter> delegates = new ArrayList<>(); 
    // make sure parent writer comes before child writer 
    deleages.add(paymentRepoItemWriter); 
    deleages.add(paymentInstallmentItemWriter); 
    writer.setDelegates(delegates); 
    return writer; 
} 
+0

我已经试过这个,但仍然有相同的错误。我在想,如果它一定是因为我打电话给'paymentDetailsTblRepository.save(payDetails)',并且在步骤或作业完成之前父项还没有被保存? – sophie

+0

如果您认为发生了这种情况,那么您遇到了交易边界问题。您需要确保块中的所有数据库操作都在同一个事务中。 –