use of org.springframework.data.mongodb.core.QueryOperations.UpdateContext in project spring-data-mongodb by spring-projects.
the class ReactiveMongoTemplate method doFindAndModify.
protected <T> Mono<T> doFindAndModify(String collectionName, Document query, Document fields, Document sort, Class<T> entityClass, UpdateDefinition update, FindAndModifyOptions options) {
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
UpdateContext updateContext = queryOperations.updateSingleContext(update, query, false);
updateContext.increaseVersionForUpdateIfNecessary(entity);
return Mono.defer(() -> {
Document mappedQuery = updateContext.getMappedQuery(entity);
Object mappedUpdate = updateContext.isAggregationUpdate() ? updateContext.getUpdatePipeline(entityClass) : updateContext.getMappedUpdate(entity);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("findAndModify using query: %s fields: %s sort: %s for class: %s and update: %s " + "in collection: %s", serializeToJsonSafely(mappedQuery), fields, sort, entityClass, serializeToJsonSafely(mappedUpdate), collectionName));
}
return executeFindOneInternal(new FindAndModifyCallback(mappedQuery, fields, sort, mappedUpdate, update.getArrayFilters().stream().map(ArrayFilter::asDocument).collect(Collectors.toList()), options), new ReadDocumentCallback<>(this.mongoConverter, entityClass, collectionName), collectionName);
});
}
use of org.springframework.data.mongodb.core.QueryOperations.UpdateContext in project spring-data-mongodb by spring-projects.
the class ReactiveMongoTemplate method doUpdate.
protected Mono<UpdateResult> doUpdate(String collectionName, Query query, @Nullable UpdateDefinition update, @Nullable Class<?> entityClass, boolean upsert, boolean multi) {
if (query.isSorted() && LOGGER.isWarnEnabled()) {
LOGGER.warn(String.format("%s does not support sort ('%s'). Please use findAndModify() instead.", upsert ? "Upsert" : "UpdateFirst", serializeToJsonSafely(query.getSortObject())));
}
MongoPersistentEntity<?> entity = entityClass == null ? null : getPersistentEntity(entityClass);
UpdateContext updateContext = multi ? queryOperations.updateContext(update, query, upsert) : queryOperations.updateSingleContext(update, query, upsert);
updateContext.increaseVersionForUpdateIfNecessary(entity);
Document queryObj = updateContext.getMappedQuery(entity);
UpdateOptions updateOptions = updateContext.getUpdateOptions(entityClass);
Flux<UpdateResult> result;
if (updateContext.isAggregationUpdate()) {
List<Document> pipeline = updateContext.getUpdatePipeline(entityClass);
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.UPDATE, collectionName, entityClass, update.getUpdateObject(), queryObj);
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
result = execute(collectionName, collection -> {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("Calling update using query: %s and update: %s in collection: %s", serializeToJsonSafely(queryObj), serializeToJsonSafely(pipeline), collectionName));
}
collection = writeConcernToUse != null ? collection.withWriteConcern(writeConcernToUse) : collection;
return multi ? collection.updateMany(queryObj, pipeline, updateOptions) : collection.updateOne(queryObj, pipeline, updateOptions);
});
} else {
Document updateObj = updateContext.getMappedUpdate(entity);
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.UPDATE, collectionName, entityClass, updateObj, queryObj);
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
result = execute(collectionName, collection -> {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("Calling update using query: %s and update: %s in collection: %s", serializeToJsonSafely(queryObj), serializeToJsonSafely(updateObj), collectionName));
}
MongoCollection<Document> collectionToUse = prepareCollection(collection, writeConcernToUse);
if (!UpdateMapper.isUpdateObject(updateObj)) {
Document filter = new Document(queryObj);
Mono<Document> deferredFilter;
if (updateContext.requiresShardKey(filter, entity)) {
if (entity.getShardKey().isImmutable()) {
deferredFilter = Mono.just(updateContext.applyShardKey(entity, filter, null));
} else {
deferredFilter = Mono.from(collection.find(filter, Document.class).projection(updateContext.getMappedShardKey(entity)).first()).defaultIfEmpty(updateObj).map(it -> updateContext.applyShardKey(entity, filter, it));
}
} else {
deferredFilter = Mono.just(filter);
}
ReplaceOptions replaceOptions = updateContext.getReplaceOptions(entityClass);
return deferredFilter.flatMap(it -> Mono.from(collectionToUse.replaceOne(it, updateObj, replaceOptions)));
}
return multi ? collectionToUse.updateMany(queryObj, updateObj, updateOptions) : collectionToUse.updateOne(queryObj, updateObj, updateOptions);
});
}
result = result.doOnNext(updateResult -> {
if (entity != null && entity.hasVersionProperty() && !multi) {
if (updateResult.wasAcknowledged() && updateResult.getMatchedCount() == 0) {
Document updateObj = updateContext.getMappedUpdate(entity);
if (containsVersionProperty(queryObj, entity))
throw new OptimisticLockingFailureException("Optimistic lock exception on saving entity: " + updateObj.toString() + " to collection " + collectionName);
}
}
});
return result.next();
}
use of org.springframework.data.mongodb.core.QueryOperations.UpdateContext in project spring-data-mongodb by spring-projects.
the class MongoTemplate method saveDocument.
protected Object saveDocument(String collectionName, Document dbDoc, Class<?> entityClass) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("Saving Document containing fields: %s", dbDoc.keySet()));
}
return execute(collectionName, collection -> {
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.SAVE, collectionName, entityClass, dbDoc, null);
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
MappedDocument mapped = MappedDocument.of(dbDoc);
MongoCollection<Document> collectionToUse = //
writeConcernToUse == null ? //
collection : collection.withWriteConcern(writeConcernToUse);
if (!mapped.hasId()) {
collectionToUse.insertOne(dbDoc);
} else {
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
UpdateContext updateContext = queryOperations.replaceSingleContext(mapped, true);
Document replacement = updateContext.getMappedUpdate(entity);
Document filter = updateContext.getMappedQuery(entity);
if (updateContext.requiresShardKey(filter, entity)) {
if (entity.getShardKey().isImmutable()) {
filter = updateContext.applyShardKey(entity, filter, null);
} else {
filter = updateContext.applyShardKey(entity, filter, collection.find(filter, Document.class).projection(updateContext.getMappedShardKey(entity)).first());
}
}
collectionToUse.replaceOne(filter, replacement, new ReplaceOptions().upsert(true));
}
return mapped.getId();
});
}
use of org.springframework.data.mongodb.core.QueryOperations.UpdateContext in project spring-data-mongodb by spring-projects.
the class MongoTemplate method doUpdate.
@SuppressWarnings("ConstantConditions")
protected UpdateResult doUpdate(String collectionName, Query query, UpdateDefinition update, @Nullable Class<?> entityClass, boolean upsert, boolean multi) {
Assert.notNull(collectionName, "CollectionName must not be null!");
Assert.notNull(query, "Query must not be null!");
Assert.notNull(update, "Update must not be null!");
if (query.isSorted() && LOGGER.isWarnEnabled()) {
LOGGER.warn(String.format("%s does not support sort ('%s'). Please use findAndModify() instead.", upsert ? "Upsert" : "UpdateFirst", serializeToJsonSafely(query.getSortObject())));
}
MongoPersistentEntity<?> entity = entityClass == null ? null : getPersistentEntity(entityClass);
UpdateContext updateContext = multi ? queryOperations.updateContext(update, query, upsert) : queryOperations.updateSingleContext(update, query, upsert);
updateContext.increaseVersionForUpdateIfNecessary(entity);
Document queryObj = updateContext.getMappedQuery(entity);
UpdateOptions opts = updateContext.getUpdateOptions(entityClass);
if (updateContext.isAggregationUpdate()) {
List<Document> pipeline = updateContext.getUpdatePipeline(entityClass);
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.UPDATE, collectionName, entityClass, update.getUpdateObject(), queryObj);
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
return execute(collectionName, collection -> {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("Calling update using query: %s and update: %s in collection: %s", serializeToJsonSafely(queryObj), serializeToJsonSafely(pipeline), collectionName));
}
collection = writeConcernToUse != null ? collection.withWriteConcern(writeConcernToUse) : collection;
return multi ? collection.updateMany(queryObj, pipeline, opts) : collection.updateOne(queryObj, pipeline, opts);
});
}
Document updateObj = updateContext.getMappedUpdate(entity);
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.UPDATE, collectionName, entityClass, updateObj, queryObj);
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
return execute(collectionName, collection -> {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("Calling update using query: %s and update: %s in collection: %s", serializeToJsonSafely(queryObj), serializeToJsonSafely(updateObj), collectionName));
}
collection = writeConcernToUse != null ? collection.withWriteConcern(writeConcernToUse) : collection;
if (!UpdateMapper.isUpdateObject(updateObj)) {
Document filter = new Document(queryObj);
if (updateContext.requiresShardKey(filter, entity)) {
if (entity.getShardKey().isImmutable()) {
filter = updateContext.applyShardKey(entity, filter, null);
} else {
filter = updateContext.applyShardKey(entity, filter, collection.find(filter, Document.class).projection(updateContext.getMappedShardKey(entity)).first());
}
}
ReplaceOptions replaceOptions = updateContext.getReplaceOptions(entityClass);
return collection.replaceOne(filter, updateObj, replaceOptions);
} else {
return multi ? collection.updateMany(queryObj, updateObj, opts) : collection.updateOne(queryObj, updateObj, opts);
}
});
}
use of org.springframework.data.mongodb.core.QueryOperations.UpdateContext in project spring-data-mongodb by spring-projects.
the class ReactiveMongoTemplate method saveDocument.
protected Mono<Object> saveDocument(String collectionName, Document document, Class<?> entityClass) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("Saving Document containing fields: %s", document.keySet()));
}
return createMono(collectionName, collection -> {
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.SAVE, collectionName, entityClass, document, null);
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
MappedDocument mapped = MappedDocument.of(document);
MongoCollection<Document> collectionToUse = //
writeConcernToUse == null ? //
collection : collection.withWriteConcern(writeConcernToUse);
Publisher<?> publisher;
if (!mapped.hasId()) {
publisher = collectionToUse.insertOne(document);
} else {
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
UpdateContext updateContext = queryOperations.replaceSingleContext(mapped, true);
Document filter = updateContext.getMappedQuery(entity);
Document replacement = updateContext.getMappedUpdate(entity);
Mono<Document> deferredFilter;
if (updateContext.requiresShardKey(filter, entity)) {
if (entity.getShardKey().isImmutable()) {
deferredFilter = Mono.just(updateContext.applyShardKey(entity, filter, null));
} else {
deferredFilter = Mono.from(collection.find(filter, Document.class).projection(updateContext.getMappedShardKey(entity)).first()).defaultIfEmpty(replacement).map(it -> updateContext.applyShardKey(entity, filter, it));
}
} else {
deferredFilter = Mono.just(filter);
}
publisher = deferredFilter.flatMapMany(it -> collectionToUse.replaceOne(it, replacement, updateContext.getReplaceOptions(entityClass)));
}
return Mono.from(publisher).map(o -> mapped.getId());
});
}
Aggregations