diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoOperations.java index 7158a224d..b83792ae6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoOperations.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoOperations.java @@ -23,6 +23,7 @@ import com.mongodb.DBCollection; import com.mongodb.DBObject; import com.mongodb.WriteResult; +import org.bson.types.ObjectId; import org.springframework.data.document.mongodb.index.IndexDefinition; import org.springframework.data.document.mongodb.query.Query; import org.springframework.data.document.mongodb.query.Update; @@ -690,13 +691,30 @@ public interface MongoOperations { WriteResult updateMulti(String collectionName, Query query, Update update); + /** + * Remove the given object from the collection by Id + * @param object + */ + void remove(Object object); + + + /** * Remove all documents from the default collection that match the provided query document criteria. * * @param queryDoc the query document that specifies the criteria used to remove a record */ void remove(Query query); - + + /** + * Remove all documents from the default collection that matchthe provided query document critera. The + * Class parameter is use to help convert the Id of the object if it is present in the query. + * @param + * @param query + * @param targetClass + */ + void remove(Query query, Class targetClass); + /** * Remove all documents from the specified collection that match the provided query document criteria. * diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java index 27748cc42..4be12a5e6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java @@ -16,6 +16,9 @@ package org.springframework.data.document.mongodb; +import static org.springframework.data.document.mongodb.query.Criteria.whereId; +import static org.springframework.data.document.mongodb.query.Query.query; + import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; @@ -165,7 +168,14 @@ public class MongoTemplate implements InitializingBean, MongoOperations, Applica if (writeResultChecking != null) { this.writeResultChecking = writeResultChecking; } - setMongoConverter(mongoConverter == null ? new SimpleMongoConverter() : mongoConverter); + if (mongoConverter == null) { + SimpleMongoConverter smc = new SimpleMongoConverter(); + smc.afterPropertiesSet(); + setMongoConverter(smc); + } else { + setMongoConverter(mongoConverter); + } + //setMongoConverter(mongoConverter == null ? new SimpleMongoConverter() : mongoConverter); } public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { @@ -808,33 +818,50 @@ public class MongoTemplate implements InitializingBean, MongoOperations, Applica * @see org.springframework.data.document.mongodb.MongoOperations#remove(com.mongodb.DBObject) */ public void remove(Query query) { - remove(getRequiredDefaultCollectionName(), query); + remove(query, null); + } + + public void remove(Object object) { + Object idValue = this.getIdValue(object); + remove(new Query(whereId().is(idValue)), object.getClass()); + } + + public void remove(Query query, Class targetClass) { + remove(getEntityCollection(targetClass), query, targetClass); } + public void remove(String collectionName, final Query query, Class targetClass) { + if (query == null) { + throw new InvalidDataAccessApiUsageException("Query passed in to remove can't be null"); + } + final DBObject queryObject = query.getQueryObject(); + if (targetClass == null) { + substituteMappedIdIfNecessary(queryObject); + } else { + substituteMappedIdIfNecessary(queryObject, targetClass, this.mongoConverter); + } + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("remove using query: " + queryObject); + } + execute(collectionName, new CollectionCallback() { + public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException { + WriteResult wr = null; + if (writeConcern == null) { + wr = collection.remove(queryObject); + } else { + wr = collection.remove(queryObject, writeConcern); + } + handleAnyWriteResultErrors(wr, queryObject, "remove"); + return null; + } + }); + } + /* (non-Javadoc) * @see org.springframework.data.document.mongodb.MongoOperations#remove(java.lang.String, com.mongodb.DBObject) */ public void remove(String collectionName, final Query query) { - if (query == null) { - throw new InvalidDataAccessApiUsageException("Query passed in to remove can't be null"); - } - final DBObject queryObject = query.getQueryObject(); - substituteMappedIdIfNecessary(queryObject); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("remove using query: " + queryObject); - } - execute(collectionName, new CollectionCallback() { - public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException { - WriteResult wr = null; - if (writeConcern == null) { - wr = collection.remove(queryObject); - } else { - wr = collection.remove(queryObject, writeConcern); - } - handleAnyWriteResultErrors(wr, queryObject, "remove"); - return null; - } - }); + remove(collectionName, query, null); } @@ -909,9 +936,6 @@ public class MongoTemplate implements InitializingBean, MongoOperations, Applica readerToUse = this.mongoConverter; } substituteMappedIdIfNecessary(query, targetClass, readerToUse); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("findOne using query: " + query + " fields: " + fields + " for class: " + targetClass); - } return execute(new FindOneCallback(query, fields), new ReadDbObjectCallback(readerToUse, targetClass), collectionName); } @@ -1006,6 +1030,32 @@ public class MongoTemplate implements InitializingBean, MongoOperations, Applica collectionName); } + protected Object getIdValue(Object object) { + if (null != mappingContext) { + PersistentEntity entity = mappingContext.getPersistentEntity(object.getClass()); + if (null != entity) { + PersistentProperty idProp = entity.getIdProperty(); + if (null != idProp) { + try { + return MappingBeanHelper.getProperty(object, idProp, Object.class, true); + } catch (IllegalAccessException e) { + throw new MappingException(e.getMessage(), e); + } catch (InvocationTargetException e) { + throw new MappingException(e.getMessage(), e); + } + } + } + } + + ConfigurablePropertyAccessor bw = PropertyAccessorFactory.forDirectFieldAccess(object); + MongoPropertyDescriptor idDescriptor = new MongoPropertyDescriptors(object.getClass()).getIdDescriptor(); + + if (idDescriptor == null) { + return null; + } + return bw.getPropertyValue(idDescriptor.getName()); + + } /** * Populates the id property of the saved object, if it's not set already. * @@ -1249,8 +1299,14 @@ public class MongoTemplate implements InitializingBean, MongoOperations, Applica public DBObject doInCollection(DBCollection collection) throws MongoException, DataAccessException { if (fields == null) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("findOne using query: " + query + " in db.collection: " + collection.getFullName()); + } return collection.findOne(query); } else { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("findOne using query: " + query + " fields: " + fields + " in db.collection: " + collection.getFullName()); + } return collection.findOne(query, fields); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/query/Criteria.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/query/Criteria.java index ae4635d5f..4f3e08334 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/query/Criteria.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/query/Criteria.java @@ -59,6 +59,10 @@ public class Criteria implements CriteriaDefinition { public static Criteria where(String key) { return new Criteria(key); } + + public static Criteria whereId() { + return new Criteria("id"); + } /** * Static factory method to create a Criteria using the provided key diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/PersonExample.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/PersonExample.java index ad5988fa0..7a8e32e06 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/PersonExample.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/PersonExample.java @@ -1,7 +1,29 @@ +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.data.document.mongodb; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; -import static org.springframework.data.document.mongodb.query.Criteria.where; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +import static org.springframework.data.document.mongodb.query.Criteria.*; import org.springframework.data.document.mongodb.query.Query; import static org.springframework.data.document.mongodb.query.Query.query; import org.springframework.data.document.mongodb.query.Update; @@ -9,23 +31,49 @@ import static org.springframework.data.document.mongodb.query.Update.update; public class PersonExample { + private static final Log log = LogFactory.getLog(PersonExample.class); @Autowired private MongoOperations mongoOps; + public static void main(String[] args) { + ApplicationContext applicationContext = new AnnotationConfigApplicationContext(PersonExampleAppConfig.class); + PersonExample example = applicationContext.getBean(PersonExample.class); + example.doWork(); + } + public void doWork() { - Person p = new Person(); + mongoOps.dropCollection("personexample"); + + PersonWithIdPropertyOfTypeString p = new PersonWithIdPropertyOfTypeString(); p.setFirstName("Sven"); p.setAge(22); - + mongoOps.save(p); + log.debug("Saved: " + p); - System.out.println(p.getId()); + p = mongoOps.findOne(query(whereId().is(p.getId())), PersonWithIdPropertyOfTypeString.class); - mongoOps.updateFirst(new Query(where("firstName").is("Sven")), new Update().set("age", 24)); + log.debug("Found: " + p); - mongoOps.updateFirst(new Query(where("firstName").is("Sven")), update("age", 24)); + // mongoOps.updateFirst(new Query(where("firstName").is("Sven")), new Update().set("age", 24)); + + // mongoOps.updateFirst(new Query(where("firstName").is("Sven")), update("age", 24)); + + mongoOps.updateFirst(query(where("firstName").is("Sven")), update("age", 24)); + p = mongoOps.findOne(query(whereId().is(p.getId())), PersonWithIdPropertyOfTypeString.class); + log.debug("Updated: " + p); + + + //mongoOps.remove( query(whereId().is(p.getId())), p.getClass()); + + mongoOps.remove(p); + + List people = mongoOps.getCollection(PersonWithIdPropertyOfTypeString.class); + + //PersonWithIdPropertyOfTypeString p2 = mongoOps.findOne(query(whereId().is(p.getId())), PersonWithIdPropertyOfTypeString.class); + + log.debug("Number of people = : " + people.size()); - mongoOps.updateFirst(query(where("firstName").is("Sven")), update("age", 24)); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/PersonExampleAppConfig.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/PersonExampleAppConfig.java new file mode 100644 index 000000000..5f2aac2fd --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/PersonExampleAppConfig.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.document.mongodb; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.mongodb.Mongo; + +@Configuration +public class PersonExampleAppConfig { + + @Bean + public Mongo mongo() throws Exception { + return new Mongo("localhost"); + } + + @Bean + public MongoTemplate mongoTemplate() throws Exception { + return new MongoTemplate(mongo(), "database", "personexample"); + } + + @Bean + public PersonExample personExample() + { + return new PersonExample(); + } +} diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/PersonWithIdPropertyOfTypeString.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/PersonWithIdPropertyOfTypeString.java index ef4739449..952529514 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/PersonWithIdPropertyOfTypeString.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/PersonWithIdPropertyOfTypeString.java @@ -47,5 +47,11 @@ public class PersonWithIdPropertyOfTypeString { public void setAge(int age) { this.age = age; } + + @Override + public String toString() { + return "PersonWithIdPropertyOfTypeString [id=" + id + ", firstName=" + + firstName + ", age=" + age + "]"; + } } diff --git a/src/docbkx/reference/mongodb.xml b/src/docbkx/reference/mongodb.xml index 53ae8706c..282e27593 100644 --- a/src/docbkx/reference/mongodb.xml +++ b/src/docbkx/reference/mongodb.xml @@ -419,16 +419,54 @@ public class AppConfig { You can save, update and delete the object as shown below - public class PersonExample { + public class PersonExample { - @Inject + private static final Log log = LogFactory.getLog(PersonExample.class); -Person p = new Person(); -p.setFirstName("Sven"); -p.setAge(22); + @Autowired + private MongoOperations mongoOps; + + public void doWork() { + + Person p = new Person(); + p.setFirstName("Sven"); + p.setAge(22); + + // Save + mongoOps.save(p); + log.debug("Saved: " + p); + + // Find + p = mongoOps.findOne(query(whereId().is(p.getId())), Person.class); + log.debug("Found: " + p); + + // Update age to 24 for Sven + mongoOps.updateFirst(query(where("firstName").is("Sven")), update("age", 24)); + p = mongoOps.findOne(query(whereId().is(p.getId())), Person.class); + log.debug("Updated: " + p); + + // Delete + mongoOps.remove(p); + // Check that deletion worked + List<Person> people = mongoOps.getCollection(Person.class); + log.debug("Number of people = : " + people.size()); -mongo +} + + This would produce the following log output (including some debug + message from MongoTemplate itself) + + Saved: PersonWithIdPropertyOfTypeString [id=4d9e82ac94fa72c65a9e7d5f, firstName=Sven, age=22] +findOne using query: { "_id" : { "$oid" : "4d9e82ac94fa72c65a9e7d5f"}} in db.collection: database.personexample +Found: PersonWithIdPropertyOfTypeString [id=4d9e82ac94fa72c65a9e7d5f, firstName=Sven, age=22] +findOne using query: { "_id" : { "$oid" : "4d9e82ac94fa72c65a9e7d5f"}} in db.collection: database.personexample +Updated: PersonWithIdPropertyOfTypeString [id=4d9e82ac94fa72c65a9e7d5f, firstName=Sven, age=24] +remove using query: { "_id" : { "$oid" : "4d9e82ac94fa72c65a9e7d5f"}} +Number of people = : 0 + + There was implicit conversion using SimpleMongoConverter between a + String and ObjectId as stored in the database.
Methods for saving documents @@ -444,14 +482,14 @@ mongo MongoTemplate import static org.springframework.data.document.mongodb.query.Criteria.where; +import static org.springframework.data.document.mongodb.query.Criteria.query; ... Person p = new Person("Bob", 33); mongoTemplate.insert("MyCollection", p); - Person qp = mongoTemplate.findOne("MyCollection", - new Query(where("id").is(p.getId())), Person.class); + Person qp = mongoTemplate.findOne("MyCollection", query(where("id").is(p.getId())), Person.class);