【发布时间】:2021-01-15 06:17:55
【问题描述】:
我有以下实体
注册程序
@Data
@NoArgsConstructor
@Entity
@EntityListeners(RegisteredProgramAuditListener.class)
public class RegisteredProgram extends Auditable<String> {
@OneToMany(mappedBy = "registeredProgram", cascade = CascadeType.ALL)
@JsonBackReference
private List<Trainer> trainerList;
@OneToMany(mappedBy = "registeredProgram", cascade = CascadeType.ALL)
@JsonBackReference
private List<Official> officialList;
}
培训师
@Data
@NoArgsConstructor
@EntityListeners(TrainerAuditListener.class)
@Entity
public class Trainer extends Auditable<String> {
@ManyToOne
@JoinColumn(name = "REGISTERED_PROGRAM_ID", nullable = false)
@JsonManagedReference
private RegisteredProgram registeredProgram;
@Type(type = "yes_no")
private Boolean isDeleted = false;
}
官方
@Data
@NoArgsConstructor
@EntityListeners(OfficialAuditListener.class)
@Entity
public class Official extends Auditable<String> {
@ManyToOne
@JoinColumn(name = "REGISTERED_PROGRAM_ID", nullable = false)
@JsonManagedReference
private RegisteredProgram registeredProgram;
@Type(type = "yes_no")
private Boolean isDeleted = false;
}
基本上,我与RegisteredProgram 有多对一关系的实体(培训师注册计划,官方注册计划)。现在我有一项服务已经达到了我的要求,通过 id 获取注册程序,我应该只包含所有 Trainer 和 Official 和 isDeleted false。请参阅以下服务:
服务
@Override
public RegisteredProgramRequestDto getRegisteredProgramDto(Long id) {
RegisteredProgram registeredProgram = registeredProgramRepository.getOne(id);
RegisteredProgramRequestDto registeredProgramRequestDto = programRegistrationMapper
.registeredProgramToRequestDto(registeredProgram);
registeredProgramRequestDto.setOfficialDtoList(
registeredProgramRequestDto.getOfficialDtoList()
.stream()
.filter(officialDto -> !officialDto.getIsDeleted())
.collect(Collectors.toList())
);
registeredProgramRequestDto.setTrainerDtoList(
registeredProgramRequestDto.getTrainerDtoList()
.stream()
.filter(trainerDto -> !trainerDto.getIsDeleted())
.collect(Collectors.toList())
);
return registeredProgramRequestDto;
}
现在,我尝试使用@Query 和@EntityGraph,这样我就可以只使用单个查询获得所需的输出。
存储库
@Repository
public interface RegisteredProgramRepository extends JpaRepository<RegisteredProgram, Long>, QuerydslPredicateExecutor<RegisteredProgram> {
@Query("select rp from RegisteredProgram rp join rp.officialList rpos join rp.trainerList rpts where rp.id = :id and rpos.isDeleted = false and rpts.isDeleted = false")
@EntityGraph(attributePaths = {"officialList", "trainerList"}, type = EntityGraph.EntityGraphType.LOAD)
RegisteredProgram getByIdNotDeleted(@Param("id") Long id);
}
更新服务
@Override
public RegisteredProgramRequestDto getRegisteredProgramDto(Long id) {
RegisteredProgram registeredProgram = registeredProgramRepository.getByIdNotDeleted(id);
return programRegistrationMapper
.registeredProgramToRequestDto(registeredProgram);
}
但是在实现之后,我遇到了以下错误:
org.hibernate.loader.MultipleBagFetchException:无法同时获取多个包:[com.tesda8.region8.program.registration.model.entities.RegisteredProgram.officialList, com.tesda8.region8.program.registration.model.entities。 RegisteredProgram.trainerList]
我已经通过 stackoverflow 搜索并遇到了this,但我仍然无法让我的查询正确执行。关于我应该如何处理这个问题的任何想法?
【问题讨论】: