【发布时间】:2015-12-26 00:52:56
【问题描述】:
我在尝试使用 Spring Data JPA 和 Hibernate 作为 JPA 提供程序进行批量插入操作时遇到问题。
我的服务中有以下方法。这是抛出异常的地方。
@Transactional
private void saveAppointments() {
// create StageFile reference object
StageFile file = new StageFile();
file.setFileName("3312_APPOINTMENT.API");
file.setDeleteFlag('N');
file.setInstitution(institution);
for (StageAppointment appointment : appointments) {
appointment.setStageFile(file);
stageAppointmentRepository.save(appointment);
}
}
@Transactional
private void saveDepartments() {
// create StageFile reference object
StageFile file = new StageFile();
file.setFileName("3312_DEPARTMENT.API");
file.setDeleteFlag('N');
file.setInstitution(institution);
for (StageDepartment department : departments) {
department.setStageFile(file);
stageDepartmentRepository.save(department);
}
}
机构是一个实例变量,提前获取。
Institution institution = institutionRepository.findByActCode(3312);
我还将实体设置为级联 PERSIST 和 MERGE。
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "stgAppointmentSeq")
@SequenceGenerator(name = "stgAppointmentSeq", sequenceName = "T_STG_APPOINTMENT_SEQ", allocationSize = 50)
@Column(name = "ID")
private Long id;
@ManyToOne(cascade = {CascadeType.PERSIST,CascadeType.MERGE}, fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "FILE_ID", referencedColumnName = "ID")
private StageFile stageFile;
@ManyToOne(cascade = {CascadeType.PERSIST,CascadeType.MERGE}, fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "STATUS_ID", referencedColumnName = "ID")
private StageStatus stageStatus;
我做错了什么?
我也确定这个问题的答案是肯定的,但是当我持久化具有所需外键引用的实体时,我必须保存完整的关联对象还是只保存 ID?不过似乎与 JPA 的目的背道而驰。
更新:
根据 cmets,我更新了代码以在单个事务中执行所有操作,但没有任何区别。
@Transactional
private void saveAppointments() {
Institution institution = institutionRepository.findByActCode(3312);
StageStatus stageStatus = stageStatusRepository.findOne(1L);
// create StageFile reference object
StageFile file = new StageFile();
file.setFileName("3312_APPOINTMENT.API");
file.setDeleteFlag('N');
file.setInstitution(institution);
for (StageAppointment appointment : appointments) {
appointment.setStageFile(file);
appointment.setStageStatus(stageStatus);
stageAppointmentRepository.save(appointment);
}
}
更新 2:
为什么这段代码有效
@Transactional
private void saveUsingTransaction() {
Institution institution = institutionRepository.findByActCode(3312);
StageStatus status = stageStatusRepository.findOne(1L);
StageFile file = new StageFile();
file.setDeleteFlag('N');
file.setFileName("3312_DIRECTORY.API");
file.setInstitution(institution);
StageDirectory directory = new StageDirectory();
directory.setLocalId("11111111111111111");
directory.setFirstName("Joe");
directory.setLastName("Joe");
directory.setPrimaryEmail("joe@gmail.com");
directory.setStageFile(file);
directory.setStageStatus(status);
stageDirectoryRepository.save(directory);
}
而这段代码没有
@Transactional
private void savePassingDirectory(StageDirectory directory) {
Institution institution = institutionRepository.findByActCode(3312);
StageStatus stageStatus = stageStatusRepository.findOne(1L);
// create StageFile reference object
StageFile file = new StageFile();
file.setFileName("3312_DIRECTORY.API");
file.setInstitution(institution);
file.setDeleteFlag('N');
directory.setStageFile(file);
directory.setStageStatus(stageStatus);
stageDirectoryRepository.save(directory);
}
【问题讨论】:
-
查看其他答案Unidirectional one to many association in Hibernate / spring-data-jpa。问题是您的交易在哪里开始和停止。您检索的实体需要在同一个事务中。
institution被加载到不同的事务中,这就是您收到错误的原因。请阅读另一个问题中的链接,这样您就可以避免几周的痛苦和沮丧。 -
更新了要在单个事务中处理的代码,但仍然出现相同的错误