Spring Data MongoDB查询触发大量PropertyReferenceException问题排查
问题原因分析
你遇到的PropertyReferenceException本质是Spring Data MongoDB在解析Criteria中的字段名时,无法匹配到实体类StorageClass的属性:
- 你在Criteria中使用的是MongoDB集合里的大写字段名
STATUS、FIELD_NUMBER,但实体类的属性大概率是小驼峰命名(比如status、fieldNumber),且没有通过@Field注解明确映射集合字段名。 - Spring Data MongoDB会尝试将Criteria中的字符串解析为实体的属性路径,找不到完整匹配的属性时,会逐步缩短字段名(比如从
STATUS尝试STATU、STAT直到S),每一次失败都会抛出PropertyReferenceException,这就是单次查询抛出超100次异常的原因。 - 尽管最终查询能返回结果,是因为MongoDB本身是大小写敏感的,直接识别集合中的大写字段,但Spring Data的属性解析过程已经触发了大量异常。
解决方案
方案1:通过@Field注解明确字段映射(推荐)
在StorageClass实体类的属性上添加@Field注解,指定对应MongoDB集合的字段名,之后用实体属性名构建Criteria:
@Document(collection = "STORAGE_CLASS") public class StorageClass { @Field("STATUS") private String status; @Field("FIELD_NUMBER") private Integer fieldNumber; // getter、setter 方法 }
构建查询时使用实体的属性名(小驼峰):
Criteria criteria = Criteria.where("status").is("E") .and("fieldNumber").is(1); Query query = new Query(criteria); List<StorageClass> result = mongoTemplate.find(query, StorageClass.class);
这种方式既符合Spring Data的规范,又能让属性解析正常完成,彻底消除异常。
方案2:直接使用MongoDB原生查询语法
如果不想修改实体类,可以直接构造原生MongoDB查询,绕过Spring Data的属性解析逻辑:
// 构造原生查询文档 BasicQuery query = new BasicQuery("{ 'STATUS': 'E', 'FIELD_NUMBER': 1 }"); List<StorageClass> result = mongoTemplate.find(query, StorageClass.class);
这种方式直接使用MongoDB的查询语法,不会触发属性路径解析,因此不会抛出PropertyReferenceException。
内容的提问来源于stack exchange,提问作者Felipe Issa
相关产品推荐
相关产品推荐

