DATAMONGO-1919 - Allow reactive-only usage of ReactiveMongoTemplate.
We now support reactive-only usage of Spring Data MongoDB without the need to use the synchronous driver or even having it on the class path. We conditionally register CodeWScope/CodeWithScope types that are bundled with the particular driver distributions. NoOpDbRefResolver is now a top-level type to be used with a reactive-only MongoMappingContext. Original Pull Request: #572
This commit is contained in:
committed by
Christoph Strobl
parent
78c2ab290d
commit
2d36fc3050
@@ -22,6 +22,7 @@ import org.springframework.data.mongodb.core.ReactiveMongoOperations;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||
import org.springframework.data.mongodb.core.SimpleReactiveMongoDatabaseFactory;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
|
||||
|
||||
import com.mongodb.reactivestreams.client.MongoClient;
|
||||
|
||||
@@ -80,7 +81,7 @@ public abstract class AbstractReactiveMongoConfiguration extends MongoConfigurat
|
||||
@Bean
|
||||
public MappingMongoConverter mappingMongoConverter() throws Exception {
|
||||
|
||||
MappingMongoConverter converter = new MappingMongoConverter(ReactiveMongoTemplate.NO_OP_REF_RESOLVER,
|
||||
MappingMongoConverter converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE,
|
||||
mongoMappingContext());
|
||||
converter.setCustomConversions(customConversions());
|
||||
|
||||
|
||||
@@ -32,8 +32,6 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.bson.BsonTimestamp;
|
||||
import org.bson.BsonValue;
|
||||
import org.bson.Document;
|
||||
@@ -77,7 +75,16 @@ import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
|
||||
import org.springframework.data.mongodb.core.aggregation.PrefixingDelegatingAggregationOperationContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
|
||||
import org.springframework.data.mongodb.core.convert.*;
|
||||
import org.springframework.data.mongodb.core.convert.DbRefResolver;
|
||||
import org.springframework.data.mongodb.core.convert.JsonSchemaMapper;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
|
||||
import org.springframework.data.mongodb.core.convert.MongoJsonSchemaMapper;
|
||||
import org.springframework.data.mongodb.core.convert.MongoWriter;
|
||||
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
import org.springframework.data.mongodb.core.convert.UpdateMapper;
|
||||
import org.springframework.data.mongodb.core.index.MongoMappingEventPublisher;
|
||||
import org.springframework.data.mongodb.core.index.ReactiveIndexOperations;
|
||||
import org.springframework.data.mongodb.core.index.ReactiveMongoPersistentEntityIndexCreator;
|
||||
@@ -96,7 +103,6 @@ import org.springframework.data.mongodb.core.mapping.event.MongoMappingEvent;
|
||||
import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions;
|
||||
import org.springframework.data.mongodb.core.query.Collation;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
|
||||
import org.springframework.data.mongodb.core.query.Meta;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
@@ -119,7 +125,6 @@ import com.mongodb.ClientSessionOptions;
|
||||
import com.mongodb.CursorType;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBCursor;
|
||||
import com.mongodb.DBRef;
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.ReadPreference;
|
||||
@@ -156,7 +161,7 @@ import com.mongodb.util.JSONParseException;
|
||||
*/
|
||||
public class ReactiveMongoTemplate implements ReactiveMongoOperations, ApplicationContextAware {
|
||||
|
||||
public static final DbRefResolver NO_OP_REF_RESOLVER = new NoOpDbRefResolver();
|
||||
public static final DbRefResolver NO_OP_REF_RESOLVER = NoOpDbRefResolver.INSTANCE;
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ReactiveMongoTemplate.class);
|
||||
private static final String ID_FIELD = "_id";
|
||||
@@ -3287,54 +3292,6 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
return new ArrayList<>(documents);
|
||||
}
|
||||
|
||||
/**
|
||||
* No-Operation {@link org.springframework.data.mongodb.core.mapping.DBRef} resolver.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
static class NoOpDbRefResolver implements DbRefResolver {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#resolveDbRef(org.springframework.data.mongodb.core.mapping.MongoPersistentProperty, org.springframework.data.mongodb.core.convert.DbRefResolverCallback)
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
public Object resolveDbRef(@Nonnull MongoPersistentProperty property, @Nonnull DBRef dbref,
|
||||
@Nonnull DbRefResolverCallback callback, @Nonnull DbRefProxyHandler proxyHandler) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#created(org.springframework.data.mongodb.core.mapping.MongoPersistentProperty, org.springframework.data.mongodb.core.mapping.MongoPersistentEntity, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
public DBRef createDbRef(org.springframework.data.mongodb.core.mapping.DBRef annotation,
|
||||
MongoPersistentEntity<?> entity, Object id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#fetch(com.mongodb.DBRef)
|
||||
*/
|
||||
@Override
|
||||
public Document fetch(DBRef dbRef) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#bulkFetch(java.util.List)
|
||||
*/
|
||||
@Override
|
||||
public List<Document> bulkFetch(List<DBRef> dbRefs) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link MongoTemplate} extension bound to a specific {@link ClientSession} that is applied when interacting with the
|
||||
* server through the driver API.
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.DBRef;
|
||||
|
||||
@@ -59,9 +60,15 @@ public interface DbRefResolver {
|
||||
* @param id will never be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
DBRef createDbRef(@Nullable org.springframework.data.mongodb.core.mapping.DBRef annotation,
|
||||
MongoPersistentEntity<?> entity,
|
||||
Object id);
|
||||
default DBRef createDbRef(@Nullable org.springframework.data.mongodb.core.mapping.DBRef annotation,
|
||||
MongoPersistentEntity<?> entity, Object id) {
|
||||
|
||||
if (annotation != null && StringUtils.hasText(annotation.db())) {
|
||||
return new DBRef(annotation.db(), entity.getCollection(), id);
|
||||
}
|
||||
|
||||
return new DBRef(entity.getCollection(), id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually loads the {@link DBRef} from the datasource.
|
||||
|
||||
@@ -104,21 +104,6 @@ public class DefaultDbRefResolver implements DbRefResolver {
|
||||
return callback.resolve(property);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#created(org.springframework.data.mongodb.core.mapping.MongoPersistentProperty, org.springframework.data.mongodb.core.mapping.MongoPersistentEntity, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public DBRef createDbRef(@Nullable org.springframework.data.mongodb.core.mapping.DBRef annotation,
|
||||
MongoPersistentEntity<?> entity, Object id) {
|
||||
|
||||
if (annotation != null && StringUtils.hasText(annotation.db())) {
|
||||
return new DBRef(annotation.db(), entity.getCollection(), id);
|
||||
}
|
||||
|
||||
return new DBRef(entity.getCollection(), id);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#fetch(com.mongodb.DBRef)
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2018 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.mongodb.core.convert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.DBRef;
|
||||
|
||||
/**
|
||||
* No-Operation {@link org.springframework.data.mongodb.core.mapping.DBRef} resolver throwing
|
||||
* {@link UnsupportedOperationException} when attempting to resolve database references.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.1
|
||||
*/
|
||||
public enum NoOpDbRefResolver implements DbRefResolver {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#resolveDbRef(org.springframework.data.mongodb.core.mapping.MongoPersistentProperty, org.springframework.data.mongodb.core.convert.DbRefResolverCallback)
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
public Object resolveDbRef(@Nonnull MongoPersistentProperty property, @Nonnull DBRef dbref,
|
||||
@Nonnull DbRefResolverCallback callback, @Nonnull DbRefProxyHandler proxyHandler) {
|
||||
throw new UnsupportedOperationException("DBRef resolution not supported!");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#fetch(com.mongodb.DBRef)
|
||||
*/
|
||||
@Override
|
||||
public Document fetch(DBRef dbRef) {
|
||||
throw new UnsupportedOperationException("DBRef resolution not supported!");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#bulkFetch(java.util.List)
|
||||
*/
|
||||
@Override
|
||||
public List<Document> bulkFetch(List<DBRef> dbRefs) {
|
||||
throw new UnsupportedOperationException("DBRef resolution not supported!");
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@ import java.util.regex.Pattern;
|
||||
|
||||
import org.bson.BsonObjectId;
|
||||
import org.bson.types.Binary;
|
||||
import org.bson.types.CodeWScope;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.mongodb.util.MongoClientVersion;
|
||||
@@ -37,6 +36,7 @@ import com.mongodb.DBRef;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public abstract class MongoSimpleTypes {
|
||||
|
||||
@@ -53,15 +53,21 @@ public abstract class MongoSimpleTypes {
|
||||
simpleTypes.add(DBRef.class);
|
||||
simpleTypes.add(ObjectId.class);
|
||||
simpleTypes.add(BsonObjectId.class);
|
||||
simpleTypes.add(CodeWScope.class);
|
||||
simpleTypes.add(org.bson.Document.class);
|
||||
simpleTypes.add(Pattern.class);
|
||||
simpleTypes.add(Binary.class);
|
||||
simpleTypes.add(UUID.class);
|
||||
|
||||
if (ClassUtils.isPresent("org.bson.types.CodeWScope", MongoSimpleTypes.class.getClassLoader())) {
|
||||
simpleTypes.add(resolveClassName("org.bson.types.CodeWScope"));
|
||||
}
|
||||
|
||||
if (ClassUtils.isPresent("org.bson.types.CodeWithScope", MongoSimpleTypes.class.getClassLoader())) {
|
||||
simpleTypes.add(resolveClassName("org.bson.types.CodeWithScope"));
|
||||
}
|
||||
|
||||
if (MongoClientVersion.isMongo34Driver()) {
|
||||
simpleTypes
|
||||
.add(ClassUtils.resolveClassName("org.bson.types.Decimal128", MongoSimpleTypes.class.getClassLoader()));
|
||||
simpleTypes.add(resolveClassName("org.bson.types.Decimal128"));
|
||||
}
|
||||
|
||||
MONGO_SIMPLE_TYPES = Collections.unmodifiableSet(simpleTypes);
|
||||
@@ -71,4 +77,8 @@ public abstract class MongoSimpleTypes {
|
||||
public static final SimpleTypeHolder HOLDER = new SimpleTypeHolder(MONGO_SIMPLE_TYPES, true);
|
||||
|
||||
private MongoSimpleTypes() {}
|
||||
|
||||
private static Class<?> resolveClassName(String className) {
|
||||
return ClassUtils.resolveClassName(className, MongoSimpleTypes.class.getClassLoader());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,8 @@ import org.reactivestreams.Publisher;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.MongoTemplateUnitTests.AutogenerateableId;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate.NoOpDbRefResolver;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.query.BasicQuery;
|
||||
@@ -107,7 +107,7 @@ public class ReactiveMongoTemplateUnitTests {
|
||||
when(aggregatePublisher.first()).thenReturn(findPublisher);
|
||||
|
||||
this.mappingContext = new MongoMappingContext();
|
||||
this.converter = new MappingMongoConverter(new NoOpDbRefResolver(), mappingContext);
|
||||
this.converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext);
|
||||
this.template = new ReactiveMongoTemplate(factory, converter);
|
||||
|
||||
}
|
||||
|
||||
@@ -39,10 +39,10 @@ import org.reactivestreams.Publisher;
|
||||
import org.springframework.data.geo.Metrics;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate.NoOpDbRefResolver;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate.ReactiveSessionBoundMongoTemplate;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
@@ -64,6 +64,7 @@ import com.mongodb.reactivestreams.client.MongoDatabase;
|
||||
* Unit tests for {@link ReactiveSessionBoundMongoTemplate}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@RunWith(MockitoJUnitRunner.Silent.class)
|
||||
@@ -124,7 +125,7 @@ public class ReactiveSessionBoundMongoTemplateUnitTests {
|
||||
factory = new SimpleReactiveMongoDatabaseFactory(client, "foo");
|
||||
|
||||
this.mappingContext = new MongoMappingContext();
|
||||
this.converter = new MappingMongoConverter(new NoOpDbRefResolver(), mappingContext);
|
||||
this.converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext);
|
||||
this.template = new ReactiveSessionBoundMongoTemplate(clientSession, new ReactiveMongoTemplate(factory, converter));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user