Spring中MongoDB查询对象数组文档仅返回匹配项报错排查
问题排查:Spring Data MongoDB查询嵌套数组元素报错“No property request found for type sampleEntity.class”
环境与场景
MongoDB的sample集合中有如下文档:
{ _id: 1, "name": "NA", request_address: [ { "state": "kyz", "city": "abc", "housenbr": [ "123", "345", "456" ] }, { "state": "pqr", "city": "def", "housenbr": [ "898", "765" ] }, { "state": "wrt", "city": "zdc" } ] }
用Mongo Shell执行以下查询,可正确返回仅包含state为pqr的request_address数组元素:
db.sample.find({_id:1},{request_address:{$elemMatch:{state:"pqr"}}})
但在Spring中编写如下代码后,报错No property request found for type sampleEntity.class:
Query query = new Query(); query.addCriteria(Criteria.where("_id").is(1)); query.addCriteria(Criteria.where("request_address").elemMatch(Criteria.where("state").is("PR"))); mongoConfiguration.mongoTemplate().findOne(query, sampleEntity.class);
错误排查细节
1. 实体类字段映射检查
这是报错的核心原因:Spring Data MongoDB对字段命名的映射规则导致解析异常
- 检查
sampleEntity类中对应MongoDB字段request_address的属性定义:- 如果实体类使用Java驼峰命名(如
requestAddress),必须添加@Field("request_address")注解明确指定MongoDB中的字段名,否则Spring会默认按驼峰转下划线规则匹配,若实体类属性名写错(比如误写为request),就会触发找不到request属性的报错。 - 正确的实体类字段定义示例:
@Document(collection = "sample") public class SampleEntity { private Integer _id; private String name; @Field("request_address") private List<RequestAddress> requestAddress; // getter、setter方法 } public class RequestAddress { private String state; private String city; private List<String> housenbr; // getter、setter方法 } - 若实体类直接使用
request_address作为属性名(不符合Java命名规范),Spring Data解析时也可能出现异常,建议改为驼峰命名配合@Field注解。
- 如果实体类使用Java驼峰命名(如
2. 查询逻辑的误区修正
原代码混淆了查询条件和投影规则:
- Mongo Shell中的查询是用
$elemMatch在投影阶段,用来返回数组中匹配的元素;而Spring代码中是把elemMatch作为查询条件,仅用于筛选包含匹配数组元素的文档,默认会返回整个文档。 - 若要实现和Mongo Shell一致的效果(仅返回匹配的
request_address元素),需要设置投影而非添加查询条件,修正后的代码:Query query = new Query(); // 设置查询条件:匹配_id=1的文档 query.addCriteria(Criteria.where("_id").is(1)); // 设置投影:仅返回state为"pqr"的request_address元素 query.fields().elemMatch("request_address", Criteria.where("state").is("pqr")); SampleEntity result = mongoConfiguration.mongoTemplate().findOne(query, SampleEntity.class);
3. 其他细节检查
- 代码笔误:原代码中
Query query = new Query;缺少括号,应为Query query = new Query();(这是编译错误,但需修正)。 - 大小写匹配:原代码中
state的值写为"PR",与Mongo文档中的"pqr"大小写不匹配,即使解决属性问题,也会查不到数据,需修正为"pqr"。
内容的提问来源于stack exchange,提问作者Ashok Illa
相关产品推荐
相关产品推荐

