I have two Entity's.
Recipe:
@jakarta.persistence.Entity
public class Recipe implements Serializable {
private static final long serialVersionUID = 1L;
@jakarta.persistence.Id @jakarta.persistence.GeneratedValue
private Integer id;
private String name;
private String instructions;
private Boolean isVegetarian;
private String numberOfServings;
@jakarta.persistence.OneToMany(cascade = CascadeType.ALL)
@Valid
private List<@Valid Ingredient> includedIngredients = new ArrayList<>();
@jakarta.persistence.OneToMany(cascade = CascadeType.ALL)
@Valid
private List<@Valid Ingredient> excludedIngredients;
public Recipe() {
super();
}
Ingredient:
@jakarta.persistence.Entity
public class Ingredient implements Serializable {
private static final long serialVersionUID = 1L;
@jakarta.persistence.Id @jakarta.persistence.GeneratedValue
private Integer id;
private String name;
private Boolean required;
public Ingredient() {
super();
}
I've created a CriteriaBuilder to allow users to find recipes that only have certain ingredients. Eg. Find me all recipes that have "Garlic" and "Onions".
I have successfully done that:
List<Predicate> ingredientsPredicates = new ArrayList<>();
for (Ingredient ingredient : fields.getIncludedIngredients()) {
ingredientsPredicates.add(builder.like(builder.lower(recipe.get("includedIngredients").<String> get("name")), "%" + ingredient.getName().toLowerCase() + "%"));
}
allPredicates.add(builder.or(ingredientsPredicates.toArray(new Predicate[]{})));
However, I also need to allow the user to find recipes that do NOT contain certain ingredients. Eg. Find me all recipes that don't have "Garlic" and "Onions".
I thought something similar would work, but no such luck....I was able to successfully use the 'notLike' method for the Recipe name, but not for the includedIngredients. Any ideas? I tried this:
List<Predicate> ingredientsPredicates = new ArrayList<>();
for (Ingredient ingredient : fields.getExcludedIngredients()) {
ingredientsPredicates.add(builder.notLike(builder.lower(recipe.get("includedIngredients").<String> get("name")), "%" + ingredient.getName().toLowerCase() + "%"));
}
allPredicates.add(builder.or(ingredientsPredicates.toArray(new Predicate[]{})));