Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exclude null properties from save operation

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?

like image 237
Modi Avatar asked Oct 19 '25 12:10

Modi


2 Answers

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);
  }
}
like image 67
Konstantin Petrukhnov Avatar answered Oct 21 '25 03:10

Konstantin Petrukhnov


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.
like image 41
Oliver Drotbohm Avatar answered Oct 21 '25 03:10

Oliver Drotbohm