org.springframework.data.mongodb.InvalidMongoDbApiUsageException: Due to limitations of the com.mongodb.BasicDocument, you can't add a second 'xxx' criteria. Query already contains...java
Query query = new Query(); query.addCriteria(Criteria.where("name").is(name)); query.addCriteria(Criteria.where("name").is(name)); // 與上一行重複使用了字段:name UserVO user = mongoTemplate.findOne(query, UserVO.class, "QWS_TEST_TABLE");
拋出異常:...you can't add a second 'name' criteria.spring
Query query = new Query(); query.addCriteria(new Criteria().andOperator(Criteria.where("name").is(name))); query.addCriteria(new Criteria().andOperator(Criteria.where("age").is(age))); // 與上一行重複使用了字段:null UserVO user = mongoTemplate.findOne(query, UserVO.class, "QWS_TEST_TABLE");
拋出異常:...you can't add a second 'null' criteria,爲何是null呢?請往下看。mongodb
首先查看addCriteria()
方法,第一找到拋異常的源頭:api
public Query addCriteria(CriteriaDefinition criteriaDefinition) { // 查詢當前字段是否存在設置了操做條件 CriteriaDefinition existing = (CriteriaDefinition)this.criteria.get(criteriaDefinition.getKey()); String key = criteriaDefinition.getKey(); if (existing == null) { // 若是不存在,那麼添加當前字段的操做條件 this.criteria.put(key, criteriaDefinition); return this; } else { // 若是已經存在,那麼拋出異常 throw new InvalidMongoDbApiUsageException(String.format("Due to limitations of the com.mongodb.BasicDocument, you can't add a second '%s' criteria. Query already contains '%s'", key, SerializationUtils.serializeToJsonSafely(existing.getCriteriaObject()))); } }
經過源碼知道:若是某個字段(key)已經存在了條件,那麼第二次去重複設置條件時,會拋出異常。回到上述問題,爲何key爲null?函數
經過查看where()
方法和Criteria
的構造函數源碼:源碼分析
// where方法 public static Criteria where(String key) { return new Criteria(key); } // 無參構造函數 public Criteria() { this.isValue = NOT_SET; this.criteriaChain = new ArrayList(); } // 有參構造函數 public Criteria(String key) { this.isValue = NOT_SET; this.criteriaChain = new ArrayList(); this.criteriaChain.add(this); this.key = key; }
發現Criteria.where("name").is(name)
最終調用了構造函數,設置了key等於「name」;而new Criteria().andOperator(Criteria.where("name").is(name))
中的new Criteria()
調用了無參的構造函數,所以key爲null。this
根源在於query.addCriteria(Criteria c)
每次調用都會設置一個相似key=value的條件,且不能重複地使用重複的字段(key)條件,因此對於比較複雜的業務,咱們只要保證addCriteria()
被調用一次便可。code
直接上代碼:orm
Query query = new Query(); Criteria c1 = Criteria.where("name").is("張三"); Criteria c2 = Criteria.where("name").is("李四"); Criteria c3 = new Criteria().andOperator(Criteria.where("name").is("王五")); Criteria c4 = new Criteria().andOperator(Criteria.where("name").is("趙六")); query.addCriteria(new Criteria().andOperator(c1, c2, c3, c4)); // 保證只調用一次addCriteria() UserVO user = mongoTemplate.findOne(query, UserVO.class, "QWS_TEST_TABLE");