Spring Batch报错:WsaCtpImcrAllocation无id属性问题求助
Spring Batch Reader步骤报错:PropertyReferenceException: No property id found for type WsaCtpImcrAllocation!
报错信息
exitCode=FAILED;exitDescription=org.springframework.data.mapping.PropertyReferenceException: No property id found for type WsaCtpImcrAllocation!
问题场景
开发批量任务实现数据库内数据克隆,任务包含多步骤,执行Reader步骤时触发上述错误。代码中明确使用sandboxId作为查询条件,WsaCtpImcrAllocation是CtpImcrAllocation的子类,二者字段大部分一致。
相关代码
Job配置类
private WsaSandbox sandbox; ... @Bean @StepScope public RepositoryItemReader<WsaCtpImcrAllocation> wsaCtpImcrAllocationCloneReader(WsaCtpImcrAllocationRepo wsaCtpImcrAllocationRepo){ RepositoryItemReader<WsaCtpImcrAllocation> wsaCtpImcrAllocationCloneRepositoryItemReader = new RepositoryItemReader<>(); wsaCtpImcrAllocationCloneRepositoryItemReader.setRepository(wsaCtpImcrAllocationRepo); wsaCtpImcrAllocationCloneRepositoryItemReader.setMethodName("findAllBySandboxId"); wsaCtpImcrAllocationCloneRepositoryItemReader.setArguments(Arrays.asList(sandbox)); wsaCtpImcrAllocationCloneRepositoryItemReader.setSort(sortMap); return wsaCtpImcrAllocationCloneRepositoryItemReader; }
Writer类
@StepScope public class CloneWsaCtpImcrAllocationCustomItemWriter implements ItemWriter<WsaCtpImcrAllocation>, StepExecutionListener{ private static final Logger log = LogManager.getLogger(CloneWsaTradeWhatIfCustomItemWriter.class); @Autowired WsaCtpImcrAllocationRepo wsaCtpImcrAllocationRepo; @Autowired WsaSandboxRepo wsaSandboxRepo; private WsaSandbox newSandbox; @Override public void write(List<? extends WsaCtpImcrAllocation> items) throws Exception { try { items.stream().forEach(allocation->wsaCtpImcrAllocationRepo.saveCopy(allocation, newSandbox)); } catch (Exception e) { log.catching(e); } } @Override public ExitStatus afterStep(StepExecution stepExecution) { return null; } @Override public void beforeStep(StepExecution stepExecution) { newSandbox = (WsaSandbox) stepExecution.getJobExecution().getExecutionContext().get("newSandbox"); } }
Repository接口
@Repository public interface WsaCtpImcrAllocationRepo extends PagingAndSortingRepository<WsaCtpImcrAllocation, CtpImcrAllocationId>, WsaCtpImcrAllocationRepoCustom { List<WsaCtpImcrAllocation> findAllBySandboxId(WsaSandbox sandboxId); Page<WsaCtpImcrAllocation> findAllBySandboxId(WsaSandbox sandboxId, Pageable pageable); ... }
子类实体WsaCtpImcrAllocation
@Entity @Table(name = "WSA_CTP_IMCR_ALLOCATION") public class WsaCtpImcrAllocation extends CtpImcrAllocation{ @ManyToOne @JoinColumn(name = "SANDBOX_ID", referencedColumnName = "ID", nullable = true) @JsonProperty @JsonView(ExtractionJsonView.FullWithChildren.class) private WsaSandbox sandboxId; @Column(name = "CUSTOM") @JsonProperty @JsonView(ExtractionJsonView.Full.class) private Boolean isCustom = false ; .... }
父类实体CtpImcrAllocation
@Entity @Table(name = "CTP_IMCR_ALLOCATION") @Inheritance (strategy = InheritanceType.TABLE_PER_CLASS) @IdClass(CtpImcrAllocationId.class) public class CtpImcrAllocation { @Column(name = "BUSINESS_DATE") @Id @JsonProperty @JsonView(ExtractionJsonView.Full.class) @Temporal(TemporalType.DATE) private Date businessDate; @Column(name = "PERIMETER") @Id @JsonProperty @JsonView(ExtractionJsonView.Full.class) private String perimeter; @Column(name="IDENTIFIER") @Id @JsonProperty @JsonView(ExtractionJsonView.Full.class) private String identifier; ... }
复合主键类CtpImcrAllocationId
public class CtpImcrAllocationId implements Serializable{ private static final long serialVersionUID = 9063822398839581588L; private Date businessDate; private String perimeter; private String identifier; public Date getBusinessDate() { return businessDate; } public void setBusinessDate(Date businessDate) { this.businessDate = businessDate; } public String getPerimeter() { return perimeter; } public void setPerimeter(String perimeter) { this.perimeter = perimeter; } public String getIdentifier() { return identifier; } public void setIdentifier(String identifier) { this.identifier = identifier; } }
问题原因
RepositoryItemReader默认会尝试使用实体的id属性作为分页排序的默认字段,但你的实体WsaCtpImcrAllocation继承自父类,使用的是复合主键(通过@IdClass定义),不存在单一的id属性,因此Spring Data无法找到对应属性,抛出PropertyReferenceException。
解决方案
- 显式指定排序字段:确保
sortMap中配置的是实体实际存在的属性,比如父类的复合主键字段或子类的sandboxId,示例如下:
Map<String, Sort.Direction> sortMap = new HashMap<>(); // 使用复合主键字段排序 sortMap.put("businessDate", Sort.Direction.ASC); sortMap.put("perimeter", Sort.Direction.ASC); sortMap.put("identifier", Sort.Direction.ASC);
- 检查分页查询逻辑:确认Repository中带
Pageable参数的findAllBySandboxId方法能正确接收排序参数,确保排序字段与实体属性一致。
内容的提问来源于stack exchange,提问作者lorenzo_.aiello
相关产品推荐
相关产品推荐

