Reputation: 2355
I'm using Spring Data for MongoDB -1.4.1.RELEASE and MongoDB 2.4.9
I'm using the mongoOperations.save() in order to update entities.
On previouse version, 1.2.0.RELEASE (due to a bug: DATAMONGO-571 ) I used to exclude some of the properties by setting their value to be null.
Now, This bug was fixed, and I'm not able to do so, but I still need to exclude some properties from the save operation (in case of update).
Does someone have an idea how this can be achieved?
Upvotes: 4
Views: 2657
Reputation: 770
I wrote abstract repository, that do partial update for single object. It expect that object contain 'id' field.
package xxx;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactory;
import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;
import java.io.Serializable;
import java.util.Map;
public abstract class ExtendedMongoRepository<T, ID extends Serializable> extends SimpleMongoRepository<T, ID> {
private Class<T> clazz;
//hidden constructor
private ExtendedMongoRepository(MongoEntityInformation metadata, MongoOperations mongoOperations) {
super(metadata, mongoOperations);
}
public ExtendedMongoRepository(MongoRepositoryFactory mongoRepositoryFactory, MongoOperations mongoOperations, Class<T> clazz) {
this(mongoRepositoryFactory.<T, ID>getEntityInformation(clazz), mongoOperations);
this.clazz = clazz;
}
protected Query getByIdQuery(ID id) {
return new Query(Criteria.where("_id").is(id));
}
/**
* Partial object update
* @param entity
* @param id
* @return
*/
public T updatePartial(T entity, ID id) {
ObjectMapper objectMapper = new ObjectMapper();
//exclude null
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
Map<String, Object> objectAsMap = objectMapper.convertValue(entity, Map.class);
//exclude id
objectAsMap.remove("id");
//add fields to update
Update u = new Update();
for (Map.Entry<String, Object> e : objectAsMap.entrySet()) {
u.set(e.getKey(), e.getValue());
}
getMongoOperations().updateFirst(getByIdQuery(id), u, clazz);
return getMongoOperations().findById(id, clazz);
}
}
And example how to use it.
public class GroupRepository extends ExtendedMongoRepository<Group, String> {
@Autowired
public GroupRepository(MongoRepositoryFactory mongoRepositoryFactory, MongoOperations mongoOperations) {
super(mongoRepositoryFactory, mongoOperations, Group.class);
}
}
Upvotes: 4
Reputation: 83051
MongoTemplate
has dedicated methods to perform partial updates like:
updateFirst(…)
- updates the first document matching a given criteria.updateMulti(…)
- updates all documents matching a given criteria.Upvotes: 1