Java 获取包含具有筛选器/条件的子实体的实体

Java 获取包含具有筛选器/条件的子实体的实体,java,spring-boot,hibernate,spring-data-jpa,Java,Spring Boot,Hibernate,Spring Data Jpa,我有以下实体 注册数据程序 @Data @NoArgsConstructor @Entity @EntityListeners(RegisteredProgramAuditListener.class) public class RegisteredProgram extends Auditable<String> { @OneToMany(mappedBy = "registeredProgram", cascade = CascadeType.ALL

我有以下实体

注册数据程序

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

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

是的:仅选择培训师和官员的查询
被删除
是错误的,这是JPA的一部分。
@EntityGraph
也是JPA的一部分,但是可以通过spring数据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);
}
公共接口RegisteredProgramRepository扩展了JpaRepository{
@查询(“从注册程序rp join rp.RPO join rp.RPT中选择rp,其中rp.id=:id和rpos.isDeleted=false和rpts.isDeleted=false”)
@EntityGraph(AttributePath={“官员”、“培训师”},type=EntityGraphType.LOAD)
RegisteredProgram getByIdNotDeleted(@Param(“id”)长id);
}

这一切都是通过JPA进行的,只需一次查询。

现在,您对
注册程序
实体的
id
做了什么?您的意思是我做了什么
id
RegisteredProgram的字段是从父类继承的,这就是为什么它没有从我的示例中指明。这就是我要问的。你是否尝试过使用联接和
EntityGraph
进行查询?嗨,我还没有尝试过,你有我可以查找的引用吗?嗨,谢谢你的输入。我尝试了您建议的解决方案,但最终出现了以下错误:
org.hibernate.loader.MultipleBagFetchException:无法同时提取多个行李
我研究并看到了此解决方案,但仍然无法正确执行查询,因为我在
注册程序
实体。JPA不能同时使用两个
列表
关系发出查询。我还将名称从officialList更改为officials,将trainerLIst更改为trainers。最后,我将lombok excludes添加到equals和toString的外键字段中。你需要小心那些东西。在从
列表
更改为
设置
并从实体中删除
@数据
,并将其替换为
@Getter
@Setter
后,解决了所有问题。谢谢你,伙计!
@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;
}
@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;
}
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);
}