通过集合中的条件过滤实体

时间:2019-12-05 15:42:22

标签: java jpa spring-data-jpa

简化的问题是:

具有一个“ A”实体,一个“ B”实体的集合(来自OneToMany关系),并使用CriteriaBuilder,如何从“ A”中获取在该集合中具有至少一个元素“ B”的元素符合条件? (例如,B的属性等于10,或者B指向另一个属性等于10的实体)。

置于上下文中:

在我的程序中,我具有以下实体

@Entity
@SequenceGenerator(name = "sequence", sequenceName = "S_EXPEDIENT")
public class Expedient {
  private Long idExpedient
  private Integer numberExpedient
  private Integer yearExpedient
  @ManyToOne
  @JoinColumn(name = "id_chamber")
  private Chamber chamber
  private Integer status
  @OneToMany(cascade = CascadeType.ALL, mappedBy = "expedient")
  private List<HistoricalAssignment> assignments = new ArrayList<HistoricalAssignment>();
  //more fields
}

@SequenceGenerator(name = "sequence", sequenceName = "S_HISTORICAL_ASSIGNMENT ")
@Entity
public class HistoricalAssignment {
  private Long idHistoricalAssignment
  @ManyToOne
  @JoinColumn(name = "id_expedient")
  private Expedient expedient;
  @ManyToOne
  @JoinColumn(name = "id_office")
  private Office office;
  //more fields
}

@SequenceGenerator(name = "sequence", sequenceName = "S_OFFICE")
@Entity
public class Office extends {
  private Long idOffice
  @ManyToOne
  @JoinColumn(name = "id_chamber")
  private Chamber chamber
  //more fields
}

@SequenceGenerator(name = "sequence", sequenceName = "S_CHAMBER")
@Entity
public class Chamber{
  private Long id_chamber
  private String description;;
  //more fields
}

我还使用Spring Data Specification来使用过滤器执行搜索。 我遇到的问题是,当试图将至少一次分配给“会议厅”的所有“权宜人”都获取时,因为我必须寻找那些在“任务”集合中至少有一个属于“办公室”的人进入“房间”。


我通过添加更多代码进行编辑。请记住,原始代码具有多个继承级别(此处已简化),并且原始模型也使用西班牙语:

public class ExpedientSpecification implements Specification<Expedient> {
    private final Integer STATUS_DELETED = -1;
    protected ExpedientFilter criteria;
    protected List<Predicate> predicates = new ArrayList<Predicate>();

    public ExpedientSpecification(ExpedientFilter criteria) {
        this.criteria=criteria;
    }

    public Predicate toPredicate(Root<Expedient> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
        //variable filters
        if(criteria.getId() != null){
            predicates.add(cb.equal(root.get("id"), criteria.getId())); 
        }
        if(criteria.getNumberExpedient() != null){
            predicates.add(criteriaBuilder.equal(root.get("numberExpedient"), criteria.getNumberExpedient()));  
        }
        if(criteria.getYearExpedient() != null){
            predicates.add(criteriaBuilder.equal(root.get("yearExpedient"), criteria.getYearExpedient()));  
        }
        //Fixed Filters
        predicates.add(criteriaBuilder.notEqual(root.get("status"), STATUS_DELETED));

        // This is where I need to add the filter. I need to get only those in the "assignments" List have at least one 
        // "Office" that belongs to a "Chamber"

        Predicate returnPredicates = cb.and(predicates.toArray(new Predicate[this.predicates.size()]));
        predicates.clear();
        return returnPredicates;
    }
}

1 个答案:

答案 0 :(得分:0)

您如何制定标准?您可以发布代码吗?

无论如何,您都可以使用条件别名正常加入oneToMany。

示例:criteria.createAlias("assignments","assignments");,然后对要过滤的分配中的属性添加限制。