'Generalize Specifications with joins
I'm using Spring Specifications to filter and sort through a class using multiple joins.
For example, I have the class ContextData
public class ContextData implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private String uuid;
@ManyToOne
@JoinColumn(name = "purpose_code", insertable = false, updatable = false)
private ClPurpose clPurpose;
@Column(name = "purpose_code")
private String clPurposeCode;
//many other fields to filter
...
}
the class ClPurpose
public class ClPurpose implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private String code;
@OneToMany(mappedBy="clPurpose")
private List<ContextData> contextData;
@OneToMany(mappedBy = "clPurpose")
private List<ClPurposeTranslation> clPurposeTranslations;
...
}
the class ClPurposeTranslation
public class ClPurposeTranslation implements Serializable {
@EmbeddedId
private TranslationPK id;
private String name;
@ManyToOne
@JoinColumn(name = "code", insertable = false, updatable = false)
private ClPurpose clPurpose;
...
}
and the class TraslationPK
@Embeddable
public class TranslationPK implements Serializable {
@Column(name = "code")
private String code;
@Enumerated(EnumType.STRING)
private LangIsoCode langIsoCode;
...
}
So I want to filter through ContextData
by the ClPurposeTranslation.name in a specific langIsoCode.
Currently I'm doing something like that
public class SearchCriteria {
private String key;
private SearchOperation operation;
private Object value;
...
}
and
public class ContextDataSpecification {
SearchCriteria criteria;
LangIsoCode langIsoCode;
@Override
public Predicate toPredicate(@NonNull Root<ContextData> root, @NonNull CriteriaQuery<?> query, @NonNull CriteriaBuilder builder) {
switch (criteria.getOperation()) {
case EQUALITY:
if ("clPurposeCode".equals(criteria.getKey())) {
Join<ContextData, ClPurposeTranslation> purposeJoin = root.join("clPurpose").join("clPurposeTranslations");
Join<Join<ContextData, ClPurposeTranslation>, TranslationPK> translationJoin = purposeJoin.join("id");
return equalAndEqualLanguagePredicate(builder, purposeJoin.get("name"), translationJoin.get("langIsoCode"));
}
//checking against many other fields...
}
}
}
Keep in mind, that i want to do this for 20+ fields in 2-3 others classes. Is there a way to generalize this process and avoid using if statements to check against the field i want to filter?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|