I have a problem with getting List entity Categories using Spring data JPA specifications. I need to get all Categories with their Recipes where Recipe.dateModified greater then some date. I don't know how to create my Predicate which would fill Collection<Recipe> in each category only those recipes that greater than this date.
@Entity
public class Category {
private int id;
private String name;
@OneToMany(mappedBy = "categories")
private Collection<Recipe> recipes;
}
@Entity
public class Recipe {
private int id;
private String name;
private Timestamp dateModified;
}
In CategoryService I getting List<Category> using Specification:
@Service
public class CategoryService {
@Autowired
private CategoryRepository categoryRepository;
public List<Category> findAll(Date date) {
return categoryRepository.findAll(where(byDateModified(date)));
}
}
I would write Specification like this, but this does not working.
public class RecipeSpec {
public static Specification<Category> byDateModified(Date date) {
return (root, query, builder) -> {
final Join<Category, Recipe> recipe = root.join(Category_.recipes, JoinType.LEFT);
return builder.greaterThan(recipe.get(Recipe_.dateModified), date);
};
}
}
try this one :
public class RecipeSpec {
public static Specification<Category> byDateModified(Date date) {
return new Specification<Category>() {
public Predicate toPredicate(Root<Category> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
List<Predicate> predicates = new ArrayList<Predicate>();
final Path<Collection<Recipe>> recipes = root.get(Recipe_.recipes);
final Path<Date> dateModified = recipes.get(Recipe_.dateModified);
return builder.greaterThan(dateModified, date);
};
}
And also make sure your entities are mapped correctly:
-you are using mappedby but the association is unidirectional!
-The collection must be initialized.
-Use Date (instead of timestamp) and add @Temporal annotation!
@Entity
public class Category {
private int id;
private String name;
//@OneToMany(mappedBy = "categories")
@OneToMany
@JoinColumn(name="categoryId")
private Collection<Recipe> recipes = new ArrayList<Recipe>();
}
@Entity
public class Recipe {
private int id;
private String name;
@Temporal(TemporalType.TIMESTAMP)
private Date dateModified;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With