You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot编写DynamoDB自定义查询报错问题排查

问题场景

基于cost字段查询DynamoDB表ProductInfo时,通过CLI执行以下命令可以正常返回正确结果:

aws dynamodb execute-statement --statement "SELECT * FROM ProductInfo WHERE cost='1000'" --endpoint-url http://localhost:8000

但在Spring Boot项目中实现相同查询逻辑时,抛出如下错误:

AmazonDynamoDBException: Can not use both expression and non-expression parameters in the same request

项目配置参照Spring Data DynamoDB配置教程编写,Repository层初始代码如下:

import org.socialsignin.spring.data.dynamodb.repository.EnableScan;
import org.socialsignin.spring.data.dynamodb.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;

@EnableScan
public interface ProductInfoRepository extends CrudRepository<ProductInfo, String> {

  @Query(fields = "select * from ProductInfo where cost = :cost")
  List<ProductInfo> findAllProductByCost(@Param("cost") String cost);
}
错误原因

报错核心原因是@Query注解属性使用错误:
spring-data-dynamodb提供的@Query注解中,fields属性仅用于声明查询需要返回的字段列表,不支持传入完整的查询语句。当把完整查询语句写在fields属性中时,框架底层会自动生成一套基于DynamoDB表达式API的查询参数,同时又会将fields中写入的语句解析为非表达式类请求参数,两类参数同时提交给DynamoDB客户端就会触发该报错。

修复方案

两种实现方式二选一即可:

  • 方案1:使用Spring Data派生查询,无需手写@Query
    因为Repository类上已经加了@EnableScan注解,支持全表扫描匹配非主键字段,直接按照Spring Data方法命名规则写查询方法即可,框架会自动生成正确的查询逻辑:
    import org.socialsignin.spring.data.dynamodb.repository.EnableScan;
    import org.springframework.data.repository.CrudRepository;
    import java.util.List;
    
    @EnableScan
    public interface ProductInfoRepository extends CrudRepository<ProductInfo, String> {
        // 框架自动派生查询逻辑,匹配cost字段等于入参的记录
        List<ProductInfo> findAllByCost(String cost);
    }
    
  • 方案2:正确使用@Query注解
    如果需要显式使用@Query,仅把需要返回的字段传入fields属性即可,查询条件通过方法名派生,不需要写完整查询语句:
    import org.socialsignin.spring.data.dynamodb.repository.EnableScan;
    import org.socialsignin.spring.data.dynamodb.repository.Query;
    import org.springframework.data.repository.CrudRepository;
    import java.util.List;
    
    @EnableScan
    public interface ProductInfoRepository extends CrudRepository<ProductInfo, String> {
        // fields仅指定返回字段,查询条件由方法名自动派生
        @Query(fields = "*")
        List<ProductInfo> findAllByCost(String cost);
    }
    

注意:如果cost不是ProductInfo表的分区键或排序键,必须保留Repository类上的@EnableScan注解,否则会抛出查询必须指定主键条件的错误。

内容的提问来源于stack exchange,提问作者Sumanth H S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 11:57:11