【问题标题】:Limit search by id通过 id 限制搜索
【发布时间】:2021-03-18 23:35:16
【问题描述】:

我想实现一个端点,用于搜索受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)]",

你知道我该如何解决这个问题吗?

【问题讨论】:

  • 您的问题不清楚。这是否意味着您希望存储库仅提供 findAllByClassId 方法而不提供其他方法?

标签: spring spring-boot spring-data-jpa spring-data


【解决方案1】:

您收到此错误是因为 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)

【讨论】:

  • 非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
  • 1970-01-01
  • 2016-05-05
  • 1970-01-01
  • 2012-01-18
  • 1970-01-01
  • 2011-10-16
相关资源
最近更新 更多