I am trying to compare a String against every column in the table. Is there an easier way to do this?
public class MySpec implements Specification<Tbl> {
private Tbl searchCriteria;
public MySpec(Tbl searchCriteria){
this.searchCriteria = searchCriteria;
}
@Override
public Predicate toPredicate(Root<Tbl> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> textPredicates = new ArrayList<>();
String searchText = "%" + searchCriteria.getSearchText() + "%";
textPredicates.add(cb.like(root.get("col1"), searchText));
textPredicates.add(cb.like(root.get("col2"), searchText));
textPredicates.add(cb.like(root.get("col3"), searchText));
textPredicates.add(cb.like(root.get("col4"), searchText));
textPredicates.add(cb.like(root.get("col5"), searchText));
textPredicates.add(cb.like(root.get("col6"), searchText));
textPredicates.add(cb.like(root.get("col7"), searchText));
textPredicates.add(cb.like(root.get("col8"), searchText));
textPredicates.add(cb.like(root.get("col9"), searchText));
return query.where(cb.or(textPredicates.toArray(new Predicate[0])
.distinct(true).getRestriction();
}
}
I don't want to have to change the specification code every time I add a new column to the table. Another option is a separate table that will hold a concatenated version of each column in a string. Such as:
TBL
Col1 | Col2 | Col3 | Col4
-----------------------------------------
1 | "Name" | "Value" | "Other Value"
TBL_CACHE
Col1 | Col2
------------------------------
1 | "Name Value OtherValue"
But I don't want to create another table for each table I want to full text search on and I don't want the maintenance of populating this data or creating a SQL job to do it automatically.