2017-01-23 15 views
2

я пытаюсь dynamicaly создать Specification для моей Spring-данных-JPA проектаИспользование JPA Criteria API для возврата всех объектов, где свойство Collection содержит определенное значение

Вот моя спецификация на данный момент:

public class DemandsSpecs implements Specification<SvDem> { 

    private static final Logger LOG = LogManager.getLogger(); 

    private final DemandsCritera critera; 
    private final List<Predicate> predicateList; 

    public DemandsSpecs(final DemandsCritera critera) { 
     this.critera = critera; 
     this.predicateList = new ArrayList<>(); 
    } 

    @Override 
    public Predicate toPredicate(final Root<SvDem> root, 
           final CriteriaQuery<?> query, 
           final CriteriaBuilder cb) { 

     this.predicateList.add(cb.between(root.get(SvDem_.hdCreation), critera.getBegin(), critera.getEnd())); 

     if (critera.getSoc() != null) { 
      LOG.debug("socId {}", critera.getSoc()); 
      this.predicateList.add(cb.equal(root.get(SvDem_.socId), critera.getSoc())); 
     } 

     if (critera.getManagementAct() != null) { 
      LOG.debug("actgesId {}", critera.getManagementAct()); 
      this.predicateList.add(cb.equal(root.get(SvDem_.actgesId), critera.getManagementAct())); 
     } 

     if (critera.getStatus() != null) { 
      LOG.debug("statutId {}", critera.getStatus()); 
      this.predicateList.add(cb.equal(root.get(SvDem_.statutId), critera.getStatus())); 
     } 

     if (!StringUtils.isBlank(critera.getId())) { 
      LOG.debug("id {}", critera.getId()); 
      this.predicateList.add(cb.like(root.get(SvDem_.id), '%' + critera.getId() + '%')); 
     } 

     return query.where(cb.and(predicateList.toArray(new Predicate[predicateList.size()]))) 
       .orderBy(cb.desc(root.get("hdCreation"))) 
       .getRestriction(); 
    } 
} 

DemandsCritera также имеет Stringmetadata.

public class DemandsCritera implements Serializable { 

    private static final Long serialVersionUID = 1L; 

    private Date begin; 
    private Date end; 
    private RfActges managementAct; 
    private String metadata; 
    private RfStatut status; 
    private RfSoc soc; 
    private String id; 

    /* getters and setters */ 
} 

SvDem обладает свойством svMetaCollection который является Collection<SvMeta>.

@Entity 
@Table(name = "sv_dem") 
public class SvDem implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @Basic(optional = false) 
    private String id; 
    @Basic(optional = false) 
    @Column(name = "HD_CREATION") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date hdCreation; 

    @Lob 
    private String user; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "svDem") 
    @JsonManagedReference 
    private Collection<SvMeta> svMetaCollection; 

    @JoinColumn(name = "ACTGES_ID", referencedColumnName = "ID") 
    @ManyToOne(optional = false) 
    private RfActges actgesId; 

    @JoinColumn(name = "STATUT_ID", referencedColumnName = "ID") 
    @ManyToOne(optional = false) 
    private RfStatut statutId; 

    @JoinColumn(name = "SOC_ID", referencedColumnName = "ID") 
    @ManyToOne(optional = false) 
    private RfSoc socId; 

    /* getters, setters and other irrelevant properties */ 

} 

Объект SvMeta имеет свойство Stringvalue

@Entity 
@Table(name = "sv_meta") 
public class SvMeta implements Serializable { 

    private static final long serialVersionUID = 1L; 
    @EmbeddedId 
    protected SvMetaPK svMetaPK; 

    @Basic(optional = false) 
    @Lob 
    private String value; 

    @JoinColumn(name = "META_ID", referencedColumnName = "ID", insertable = false, updatable = false) 
    @ManyToOne(optional = false) 
    private RfMeta rfMeta; 

    @JoinColumn(name = "DEM_ID", referencedColumnName = "ID", insertable = false, updatable = false) 
    @ManyToOne(optional = false) 
    @JsonBackReference 
    private SvDem svDem; 
} 

Я хочу, чтобы вернуть все SvDem, где любой из его SvMeta имеет value равна DemandsCritera.metadata.

Как я могу это достичь?

ответ

1

мне просто нужно, чтобы добавить это к моему toPredicate метод DemandsSpecs:

if (!StringUtils.isBlank(critera.getMetadata())) { 
     LOG.debug("metadata {}", critera.getMetadata()); 
     Join<SvDem, SvMeta> metas = root.join(SvDem_.svMetaCollection); 
     this.predicateList.add(cb.equal(metas.get(SvMeta_.value), critera.getMetadata())); 
    }