Java 在Spring数据JPA中获取父实体的列表以及子实体的筛选集合

Java 在Spring数据JPA中获取父实体的列表以及子实体的筛选集合,java,spring,hibernate,spring-data-jpa,projection,Java,Spring,Hibernate,Spring Data Jpa,Projection,所以我已经在这个问题上纠缠了大约半天,所以我想知道我是否把事情复杂化了 我的应用程序有三个不同的Java对象类:祖父母、父母和孩子。每个祖父母都包含一个父母列表,每个父母都包含一个孩子列表。子对象具有一个“IswelleHaved”属性,该属性是布尔值 我们使用SpringDataJPA和Hibernate将数据映射到数据库。我们的应用程序包含许多嵌套实体和循环关系,我们依靠投影来降低请求大小 问题:给定祖父母id,我想返回所有父母的列表(作为预测)。我希望每个家长都包含一个孩子投影列表,但前提

所以我已经在这个问题上纠缠了大约半天,所以我想知道我是否把事情复杂化了

我的应用程序有三个不同的Java对象类:祖父母、父母和孩子。每个祖父母都包含一个父母列表,每个父母都包含一个孩子列表。子对象具有一个“IswelleHaved”属性,该属性是布尔值

我们使用SpringDataJPA和Hibernate将数据映射到数据库。我们的应用程序包含许多嵌套实体和循环关系,我们依靠投影来降低请求大小

问题:给定祖父母id,我想返回所有父母的列表(作为预测)。我希望每个家长都包含一个孩子投影列表,但前提是孩子表现良好。集合中的其余子项应从集合中筛选出来

实现这一目标的最简单方法是什么?我们目前没有使用Hibernate过滤器,我也不想介绍它们,因为我们在其他任何地方都不可能需要它们(无论哪种方式,它是否适合此用途?)。我使用了JPA标准API谓词(很少),但发现很难使其适应这种特定场景。本机查询是正确的选择吗?我已经开始朝这个方向走了,但是由于所有嵌套的依赖关系,我在将所有字段映射到Spring实体时遇到了一些问题,所以在继续之前,我只想确保我的方向是正确的

我的(简化的)父实体类如下所示:

@Entity
@Table(name="parent"
public class Parent {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="parent_id")
    Integer id;

    Integer grandparentId; 

    @OneToMany(mappedBy = "parent")
    List<Child> children;
}
父存储库接口:

@RepositoryRestResource(excerptProjection = ParentProjection.class)
public interface ParentRepository extends JpaProjectionRepository<Parent, Integer, ParentProjection> {

    List<ParentProjection> findAllByGrandparent_Id(Integer grandpaId);
}
@RepositoryRestResource(摘录projection=ParentProjection.class)
公共接口ParentRepository扩展了JPAProjectRepository{
列出findAllByGrandparent\u Id(整数祖父母Id);
}
正如您所说:

我希望每个家长都包含一个孩子投影列表,但前提是孩子表现良好

ListallChilderns=parentsList.stream().map(parent>dao.findchildernByParentId()).collect(Collectors.List());
allChilderns.stream().filter(childern->childern.iswellehaved()==true).collect(collector.toList());
  • 通过祖父母——你正在做的那一个——找到所有的父母
  • 一旦你得到了所有的父母,每个父母都找到了Childernbyparentid
  • 然后根据条件过滤出子对象

  • 让我知道:)

    您可以在集合上使用hibernate的@Where注释。大概是

    @Entity
    @Table(name="parent"
    public class Parent {
    
        @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name="parent_id")
        Integer id;
    
        Integer grandparentId; 
    
        @Where(clause = "isWellBehaved=true")
        @OneToMany(mappedBy = "parent")
        List<Children> children;
    }
    
    @实体
    @表(name=“parent”
    公共类父类{
    @Id@GeneratedValue(策略=GenerationType.IDENTITY)
    @列(name=“parent\u id”)
    整数id;
    整数祖父母ID;
    @其中(第条=“IswelleHaved=true”)
    @OneToMany(mappedBy=“家长”)
    列出儿童名单;
    }
    
    为什么要将所有数据加载到内存中以应用过滤器,而这可以在数据库级别完成?但我如何返回父级列表?我无法设置Children属性,因为我从数据库返回的父级只是投影,不可修改。这是我一直在努力解决的问题。有吗任何情况下,您都可以返回实体列表而不是投影,然后在筛选出结果时,可能只是为了返回而创建另一个投影。这不适用于带有Pageable参数的查询,因为父行基于子行重复,并导致错误的Pageable实现。这看起来像是hat可能会起作用,但在其他一些情况下,我需要集合包含所有子项。你知道我该如何实现这一点吗?我认为你应该声明另一个类似的集合变量,使用不同的名称,并且没有@Where注释。使两个变量的关联都是惰性的,并获取适合你目的的变量。为什么不使用simply加载所有行为良好的子项,然后按父项(在Java中)将它们分组,作为父项到子项列表的映射?这不如让一个父实体只有经过筛选的子项,但数据相同,而不需要加载稍后将被过滤掉的子项。
    List<childerns>allChilderns=parentsList.stream().map(parent>dao.findchildernByParentId()).collect(Collectors.List());
    
    allChilderns.stream().filter(childern->childern.isWellBehaved()==true).collect(Collectors.toList());
    
    @Entity
    @Table(name="parent"
    public class Parent {
    
        @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name="parent_id")
        Integer id;
    
        Integer grandparentId; 
    
        @Where(clause = "isWellBehaved=true")
        @OneToMany(mappedBy = "parent")
        List<Children> children;
    }