0

1.) I want to get an Expression using an Expression and a String Pattern. It should become true if the Expression is included in the String Pattern not the other way.

The string pattern can look like "MFD" or "MF" or any other combination of the three letters M,F,D. The Expression is either M, F or D.

So far I have the following code, but i think there is a better solution.


public class AthleteSpecification implements Specification<Athlete> {

    private String gender;

    public AthleteSpecification(String gender) {
        super();
        this.gender = gender;
    }



@Override
    public Predicate toPredicate(Root<Athlete> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
        Predicate p = cb.disjunction();

        if (this.gender == null) {
            return cb.conjunction();
        } else {

            Expression<Boolean> isMaleOrFemaleorDivers;

            if (this.gender != null) {

//              This is a working solution but not nice         
                Expression<Boolean> isMale = cb.equal(root.get("gender"), gender.contains("M") ? "M" : "");
                Expression<Boolean> isMaleOrFemale = cb.or(isMale,
                        cb.equal(root.get("gender"), gender.contains("F") ? "F" : ""));
                isMaleOrFemaleorDivers = cb.or(isMaleOrFemale,
                        cb.equal(root.get("gender"), gender.contains("D") ? "D" : ""));


//              This is not a solution because i think it only checks if the String is in the Expression<String> not the other way
//              Expression<Integer> test = cb.locate(root.get("gender"), gender);
//              isMaleOrFemaleorDivers = cb.greaterThan(test, 0);


            } else {
                isMaleOrFemaleorDivers = cb.conjunction();
            }

            p.getExpressions().add(cb.and(isNameMatching, isMaleOrFemaleorDivers));

            return p;
        }

    } 

}
dasLicht
  • 141
  • 7
  • At Stack Overflow we prefer one question per question. Please edit this question to contain only one question and create a separate question for the other one. – Jens Schauder Feb 12 '20 at 07:32
  • I have edited my question – dasLicht Feb 12 '20 at 08:30
  • Check if the answer to this question helps -- https://stackoverflow.com/questions/42530677/jpa-criteria-builder-in-clause-query – S B Feb 14 '20 at 13:36

1 Answers1

0

You should use like() function.

The following code does what you want. This is written in Kotlin.

    val specification = Specification<LocationEntity> { root, query, builder ->
        val predicates = mutableListOf<Predicate>()
        if (name != null) {
            predicates.add(builder.like(root.get("name"),  "%$name%"))
        }
        builder.and(*predicates.toTypedArray())
    }
Hasan Mhd Amin
  • 220
  • 2
  • 11