我无法使用我的子表(TBL_PAYMENT_DETAILS
)添加Spring批处理的外键关系。
我收到此错误:Not-null property references a transient value
在此行:paymentDetailsTblRepository.save(payDetails);
我试图通过调用两个作者来替换compositePaymentItemWriter
:paymentRepoItemWriter
和paymentInstallmentItemWriter
认为paymentRepoItemWriter
会先保留父作品,所以我可以将它引用到我的儿童表。但同样的问题。
我在想是否一定是因为我正在调用paymentDetailsTblRepository.save(payDetails)
并且在Step
或Job
完成之前父级尚未保留?
父表:
@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 :(得分: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;
}