DATAMONGO-2241 - Polishing.

Ensure to have to DbRefResolver operate within the session while reusing the MappingContext.

Original Pull Request: #734
This commit is contained in:
Christoph Strobl
2019-04-01 09:17:47 +02:00
parent 13db06d345
commit bdf7ec7c9b
3 changed files with 42 additions and 9 deletions

View File

@@ -33,7 +33,6 @@ import org.bson.codecs.Codec;
import org.bson.conversions.Bson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
@@ -260,7 +259,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
this.mongoDbFactory = dbFactory;
this.exceptionTranslator = that.exceptionTranslator;
this.sessionSynchronization = that.sessionSynchronization;
this.mongoConverter = that.mongoConverter;
// we need to (re)create the MappingMongoConverter as we need to have it use a DbRefResolver that operates within
// the sames session. Otherwise loading referenced objects would happen outside of it.
if (that.mongoConverter instanceof MappingMongoConverter) {
this.mongoConverter = ((MappingMongoConverter) that.mongoConverter).with(dbFactory);
} else {
this.mongoConverter = that.mongoConverter;
}
this.queryMapper = that.queryMapper;
this.updateMapper = that.updateMapper;
this.schemaMapper = that.schemaMapper;

View File

@@ -28,7 +28,9 @@ import org.springframework.context.ApplicationContextAware;
import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.convert.EntityInstantiator;
import org.springframework.data.convert.EntityInstantiators;
import org.springframework.data.convert.TypeMapper;
import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.MappingException;
@@ -1596,6 +1598,26 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return dbRefResolver.bulkFetch(references);
}
/**
* Create a new {@link MappingMongoConverter} using the given {@link MongoDbFactory} when loading {@link DBRef}.
*
* @return new instance of {@link MappingMongoConverter}. Never {@literal null}.
* @since 2.1.6
*/
public MappingMongoConverter with(MongoDbFactory dbFactory) {
MappingMongoConverter target = new MappingMongoConverter(new DefaultDbRefResolver(dbFactory), mappingContext);
target.applicationContext = applicationContext;
target.conversions = conversions;
target.spELContext = spELContext;
target.setInstantiators(instantiators);
target.typeMapper = typeMapper;
target.afterPropertiesSet();
return target;
}
/**
* Returns whether the given {@link Iterable} contains {@link DBRef} instances all pointing to the same collection.
*

View File

@@ -29,15 +29,15 @@ import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.test.util.MongoTestUtils;
import org.springframework.data.mongodb.test.util.MongoVersion;
import org.springframework.data.mongodb.test.util.MongoVersionRule;
import org.springframework.data.mongodb.test.util.ReplicaSet;
import org.springframework.data.util.Version;
import org.springframework.test.util.ReflectionTestUtils;
import com.mongodb.ClientSessionOptions;
import com.mongodb.MongoClient;
@@ -92,15 +92,19 @@ public class ClientSessionTests {
}
@Test // DATAMONGO-2241
public void shouldReuseConfiguredConverter() {
public void shouldReuseConfiguredInfrastructure() {
ClientSession session = client.startSession(ClientSessionOptions.builder().causallyConsistent(true).build());
MongoConverter converter = template.getConverter();
MongoConverter sessionTemplateConverter = template.withSession(() -> session)
.execute(MongoOperations::getConverter);
MappingMongoConverter source = MappingMongoConverter.class.cast(template.getConverter());
MappingMongoConverter sessionTemplateConverter = MappingMongoConverter.class
.cast(template.withSession(() -> session).execute(MongoOperations::getConverter));
assertThat(sessionTemplateConverter).isSameAs(converter);
assertThat(sessionTemplateConverter.getMappingContext()).isSameAs(source.getMappingContext());
assertThat(ReflectionTestUtils.getField(sessionTemplateConverter, "conversions"))
.isSameAs(ReflectionTestUtils.getField(source, "conversions"));
assertThat(ReflectionTestUtils.getField(sessionTemplateConverter, "instantiators"))
.isSameAs(ReflectionTestUtils.getField(source, "instantiators"));
}
@Test // DATAMONGO-1920