Question

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?

Was it helpful?

Solution 2

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.

OTHER TIPS

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);
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top