spring - 通过 id 限制搜索
问题描述
我想实现一个端点,用于搜索受 class_id 限制的表:
桌子:
@Entity
@Table(name = "class_items")
public class ClassItems implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, updatable = false, nullable = false)
private int id;
@Column(name = "class_id", length = 20)
private Integer classId;
@Column(name = "title", length = 75)
private String title;
}
@PostMapping("/{class_id}/find")
public Page<ClassCategoriesFullDTO> search(@PathVariable("class_id") Integer classId, @Valid ClassCategoriesSearchParams params, Pageable pageable) {
Page<ClassCategoriesFullDTO> list = classItemsRestService.findClassItemsByClassId(classId, params, pageable);
return list;
}
public Page<ClassCategoriesFullDTO> findClassItemsByClassId(Integer classId, ClassCategoriesSearchParams params, Pageable pageable) {
// Limit here queries by classId
Specification<Product> spec = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
if (params.getTitle() != null) {
predicates.add(cb.equal(root.get("title"), params.getTitle()));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
return classItemsService.findAllByClassId(spec, pageable).map(classItemsMapper::toFullDTO);
}
@Service
@Transactional
public class ClassItemsServiceImpl implements ClassItemsService {
@PersistenceContext
private EntityManager entityManager;
private ClassItemsRepository dao;
@Autowired
public ClassItemsServiceImpl(ClassItemsRepository dao) {
this.dao = dao;
}
public Page<ClassItems> findAllByClassId(Specification spec, Pageable pageable) {
return this.dao.findAllByClassId(spec, pageable);
}
}
@Repository
public interface ClassItemsRepository extends JpaRepository<ClassItems, Long>, JpaSpecificationExecutor<ClassItems> {
Page<ClassItems> findAllByClassId(Specification spec, Pageable pageable);
}
我得到错误:
参数值[org.service.ClassItemsRestServiceImpl$$Lambda$1987/0x0000000801e21440@3c4de5a9] did not match expected type [java.lang.Integer (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [org.service.ClassItemsRestServiceImpl$$Lambda$1987/0x0000000801e21440@3c4de5a9] did not match expected type [java.lang.Integer (n/a)]",
你知道我该如何解决这个问题吗?
解决方案
您收到此错误是因为 Spring Data 正在尝试基于方法 name 生成查询findAllByClassId
,因此它需要一个整数作为第一个参数。
使用规范时,您应该使用JpaSpecificationExecutor
. 添加您自己的带有规范的方法作为参数是行不通的。如果要过滤classId
,请将适当的过滤器附加到规范本身。
编辑解决方案是在构建规范时添加额外的条件:
Specification<Product> spec = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
if (params.getTitle() != null) {
predicates.add(cb.equal(root.get("title"), params.getTitle()));
}
predicates.add(cb.equal(root.get("classId"), classId));
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
然后,在 中ClassItemsServiceImpl
,调用dao.findAll(spec)
推荐阅读
- sql - 使用 BigQuery 中的条件计算运行总计
- css - 为什么我的菜单项在桌面大小时不显示?
- git - 如何使用 GitHub API 从特定的提交哈希中获取文件?
- python - Python 中的 Jupyter 笔记本
- python - Python If None then check not None from other variables
- vue.js - 如何在 css 中更改 Vuetify v-icon 颜色
- javascript - HTML5 画布上的网格游戏
- kotlin - 来自 Android 设备的 Ktor 服务器上的信令错误
- jestjs - 使用通过 Webpack 使用 React 组件的玩笑运行时的编译错误
- r - R 因“未实现这些类型的比较”而失败