我使用Spring数据JPA规范获取List实体类别时遇到问题。我需要使用他们的食谱获得所有类别Recipe.dateModified
大于某个日期。我不知道如何创建我的Predicate,它会在每个类别中填充Collection<Recipe>
只有那些大于此日期的食谱。
@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;
}
在CategoryService
我使用规范获取List<Category>
:
@Service
public class CategoryService {
@Autowired
private CategoryRepository categoryRepository;
public List<Category> findAll(Date date) {
return categoryRepository.findAll(where(byDateModified(date)));
}
}
我会像这样编写规范,但这不起作用。
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);
};
}
}
答案 0 :(得分:0)
在CategoryRepository Implementation类中,添加此方法
public Category findAll(Date dateModified) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Category> query = builder.createQuery(Category.class);
Root<Category> category = query.from(Category.class);
ParameterExpression<Date> dateParam = builder.parameter(Date.class);
query.select(category).where(builder.greaterThan(category.get(Category_.recipes).get(Recipe_.dateModified), dateParam));
return em.createQuery(query)
.setParameter(dateParam, dateModified)
.getSingleResult();
}
MetaModel类用于上面的代码中。如果没有生成元模型类,则在pom文件中添加此插件以自动生成元模型类..
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>2.2.4</version>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<processors>
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
</processors>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>5.2.2.Final</version>
</dependency>
</dependencies>
</plugin>
答案 1 :(得分:0)
试试这个:
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);
};
}
并确保您的实体正确映射:
- 你正在使用mappedby,但关联是单向的!
- 必须初始化集合。
- 使用日期(而不是时间戳)并添加@Temporal注释!
@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;
}