Reputation: 515
I am trying to dynamicaly create a Specification
for my Spring-data-jpa project
Here is my specification for the moment:
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();
}
}
The DemandsCritera
also have a String
property metadata
.
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 has a property svMetaCollection
which is a 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 */
}
The SvMeta object has a String
property value
@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;
}
I want to return all the SvDem
where any of its SvMeta
has a value
equals to the DemandsCritera.metadata
.
How can I achieve that?
Upvotes: 4
Views: 2855
Reputation: 515
I just needed to add this to my toPredicate
method of 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()));
}
Upvotes: 4