按 id 限制搜索
Limit search by id
我想实现一个端点,用于搜索受 class_id 限制的 table:
Table:
@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$$Lambda87/0x0000000801e21440@3c4de5a9] did not match expected type [java.lang.Integer (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [org.service.ClassItemsRestServiceImpl$$Lambda87/0x0000000801e21440@3c4de5a9] did not match expected type [java.lang.Integer (n/a)]",
你知道我怎么解决这个问题吗?
您收到此错误是因为 Spring Data 正在尝试根据方法名称 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)
我想实现一个端点,用于搜索受 class_id 限制的 table:
Table:
@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$$Lambda87/0x0000000801e21440@3c4de5a9] did not match expected type [java.lang.Integer (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [org.service.ClassItemsRestServiceImpl$$Lambda87/0x0000000801e21440@3c4de5a9] did not match expected type [java.lang.Integer (n/a)]",
你知道我怎么解决这个问题吗?
您收到此错误是因为 Spring Data 正在尝试根据方法名称 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)