我发现标准做法的行为不一致,并且通过Spring Data JPA作为Spring Batch作业的一部分来保持JPA双向关系。我的工作步骤如下:
@Bean
public Step importSinglePatient(StepBuilderFactory stepBuilderFactory,
ItemReader<Patient> singlePatientReader,
ItemWriter<Patient> patientWriter) {
return stepBuilderFactory.get("importSinglePatient")
.<Patient, Patient>chunk(1)
.reader(singlePatientReader)
.writer(patientWriter)
.build();
}
@Bean
public Step importSingleEncounter(StepBuilderFactory stepBuilderFactory,
ItemReader<Encounter> singleEncounterReader,
ItemWriter<Encounter> encounterWriter) {
return stepBuilderFactory.get("importSingleEncounter")
.<Encounter, Encounter>chunk(1)
.reader(singleEncounterReader)
.writer(encounterWriter)
.build();
}
这两个域是Patient
(父)和Encounter
(子)。它们如下所示:
@Entity
public class Patient implements Serializable {
public static final long serialVersionUID = 1L;
@Id
private Long patientId;
@OneToMany(mappedBy = "patient", cascade = CascadeType.ALL)
private List<Encounter> encounters;
// getters & setters
}
@Entity
public class Encounter implements Serializable {
public static final long serialVersionUID = 1L;
@Id
private Long encounterId;
@ManyToOne
@JoinColumn(name = "patient_id")
private Patient patient;
// getters & setters
}
接下来,假设所有患者都已从源数据库中读入并作为上一步骤的一部分保留。执行的下一步是通过带有JdbcPagingItemReader<Encounter>
的{{1}}读取所有遭遇者(孩子)。 RowMapper<Encounter>
代码如下所示:
RowMapper
然后将@Component
public class EncounterRowMapper implements RowMapper<Encounter> {
@Autowired
private PatientRepository patientRepository
public static final String PATIENT_ID = "PATIENT_ID";
@Override
public Encounter mapRow(ResultSet rs, int rowNum) throws SQLException {
Encounter encounter = new Encounter;
Patient patient = patientRepository.findOne(rs.getLong(PATIENT_ID));
encounter.setPatient(patient);
return encounter;
}
}
传递给Encounter
,将遇到者保存到RepositoryItemWriter<Encounter>
。
我的理解是,这不是最佳做法,原因如下:
EncounterRepository
;但是,我认为这不适合RowMapper应该做的事情。也许我错在这里。可以将其移至patient.getEncounters.add(encounter)
并将ItemProcessor<Encounter, Patient>
更改为ItemWriter
。不过,我会不断地坚持我的父母,如果这个孩子是这个关系的所有者,这是不理想的 - 父母也不会改变。ItemWriter<Patient>
。patient.getEncounters.add(encounter)
,ItemReader
和ItemProcessor
模型做到这一点的好方法。 希望有人能帮助我理解为什么我没有看到#2和#1&amp; #3。