首页 > 解决方案 > 获取一个实体,包括具有过滤器/条件的子实体

问题描述

我有以下实体

注册程序

@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基本上,我的实体与, (Trainer-RegisteredProgram, Official-RegisteredProgram)具有多对一的关系。现在我有一个服务,它通过 id 获取注册程序,我应该只包括所有TrainerisDeletedOfficial为假的。我有以下服务:

服务

@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;
}

我的问题是,有什么方法可以更有效地改善我的服务?

标签: javaspring-boothibernatespring-data-jpa

解决方案


是:仅选择培训师和官员的查询isDeleted是错误的,这是 JPA 的一部分。A@EntityGraph也是 JPA 的一部分,但可以通过 spring-data-jpa 更轻松地完成。

public interface RegisteredProgramRepository extends JpaRepository<RegisteredProgram, Long>{
    @Query("select rp from RegisteredProgram rp join rp.officials rpos join rp.trainers rpts where rp.id = :id and rpos.isDeleted = false and rpts.isDeleted = false")
    @EntityGraph(attributePaths = {"officials", "trainers"}, type = EntityGraphType.LOAD)
    RegisteredProgram getByIdNotDeleted(@Param("id") Long id);
}

这通过 JPA 使用单个查询完成所有操作。


推荐阅读