Skip to content

Introduce SessionSynchronization.NEVER, reduce allocations #3809

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.3.0-SNAPSHOT</version>
<version>3.3.0-3760-SNAPSHOT</version>
<packaging>pom</packaging>

<name>Spring Data MongoDB</name>
Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb-benchmarks/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.3.0-SNAPSHOT</version>
<version>3.3.0-3760-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb-distribution/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.3.0-SNAPSHOT</version>
<version>3.3.0-3760-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.3.0-SNAPSHOT</version>
<version>3.3.0-3760-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ private static MongoDatabase doGetMongoDatabase(@Nullable String dbName, MongoDa

Assert.notNull(factory, "Factory must not be null!");

if (!TransactionSynchronizationManager.isSynchronizationActive()) {
if (sessionSynchronization == SessionSynchronization.NEVER
|| !TransactionSynchronizationManager.isSynchronizationActive()) {
return StringUtils.hasText(dbName) ? factory.getMongoDatabase(dbName) : factory.getMongoDatabase();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ private static Mono<MongoDatabase> doGetMongoDatabase(@Nullable String dbName, R

Assert.notNull(factory, "DatabaseFactory must not be null!");

if (sessionSynchronization == SessionSynchronization.NEVER) {
return getMongoDatabaseOrDefault(dbName, factory);
}

return TransactionSynchronizationManager.forCurrentTransaction()
.filter(TransactionSynchronizationManager::isSynchronizationActive) //
.flatMap(synchronizationManager -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,20 @@
*/
package org.springframework.data.mongodb;

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;

/**
* {@link SessionSynchronization} is used along with {@link org.springframework.data.mongodb.core.MongoTemplate} to
* define in which type of transactions to participate if any.
* {@link SessionSynchronization} is used along with {@code MongoTemplate} to define in which type of transactions to
* participate if any.
*
* @author Christoph Strobl
* @author Mark Paluch
* @since 2.1
* @see MongoTemplate#setSessionSynchronization(SessionSynchronization)
* @see MongoDatabaseUtils#getDatabase(MongoDatabaseFactory, SessionSynchronization)
* @see ReactiveMongoTemplate#setSessionSynchronization(SessionSynchronization)
* @see ReactiveMongoDatabaseUtils#getDatabase(ReactiveMongoDatabaseFactory, SessionSynchronization)
*/
public enum SessionSynchronization {

Expand All @@ -34,5 +41,12 @@ public enum SessionSynchronization {
/**
* Synchronize with native MongoDB transactions initiated via {@link MongoTransactionManager}.
*/
ON_ACTUAL_TRANSACTION;
ON_ACTUAL_TRANSACTION,

/**
* Do not participate in ongoing transactions.
*
* @since 3.2.5
*/
NEVER;
}
Original file line number Diff line number Diff line change
Expand Up @@ -156,5 +156,14 @@ public Boolean isIsolated() {
public List<ArrayFilter> getArrayFilters() {
return delegate.getArrayFilters();
}

/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.UpdateDefinition#hasArrayFilters()
*/
@Override
public boolean hasArrayFilters() {
return delegate.hasArrayFilters();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ class UpdateContext extends QueryContext {

UpdateContext(MappedDocument update, boolean upsert) {

super(new BasicQuery(new Document(BsonUtils.asMap(update.getIdFilter()))));
super(new BasicQuery(BsonUtils.asDocument(update.getIdFilter())));
this.multi = false;
this.upsert = upsert;
this.mappedDocument = update;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public Object get(MongoPersistentProperty property) {
*/
@Nullable
public Object getRawId(MongoPersistentEntity<?> entity) {
return entity.hasIdProperty() ? get(entity.getRequiredIdProperty()) : BsonUtils.asMap(document).get("_id");
return entity.hasIdProperty() ? get(entity.getRequiredIdProperty()) : BsonUtils.get(document, "_id");
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -1316,21 +1315,22 @@ protected Map<Object, Object> readMap(ConversionContext context, Bson bson, Type
return map;
}

for (Entry<String, Object> entry : sourceMap.entrySet()) {
sourceMap.forEach((k, v) -> {

if (typeMapper.isTypeKey(entry.getKey())) {
continue;
if (typeMapper.isTypeKey(k)) {
return;
}

Object key = potentiallyUnescapeMapKey(entry.getKey());
Object key = potentiallyUnescapeMapKey(k);

if (!rawKeyType.isAssignableFrom(key.getClass())) {
key = doConvert(key, rawKeyType);
}

Object value = entry.getValue();
Object value = v;
map.put(key, value == null ? value : context.convert(value, valueType));
}

});

return map;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ default Object convertId(@Nullable Object id, Class<?> targetType) {
if (ObjectId.isValid(id.toString())) {
return new ObjectId(id.toString());
}

// avoid ConversionException as convertToMongoType will return String anyways.
return id;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,11 @@ public Document getMappedSort(Document sortObject, @Nullable MongoPersistentEnti
Assert.notNull(sortObject, "SortObject must not be null!");

if (sortObject.isEmpty()) {
return new Document();
return BsonUtils.EMPTY_DOCUMENT;
}

Document mappedSort = mapFieldsToPropertyNames(sortObject, entity);
mapMetaAttributes(mappedSort, entity, MetaMapping.WHEN_PRESENT);
return mappedSort;
return mapMetaAttributes(mappedSort, entity, MetaMapping.WHEN_PRESENT);
}

/**
Expand All @@ -215,42 +214,51 @@ public Document getMappedFields(Document fieldsObject, @Nullable MongoPersistent
Assert.notNull(fieldsObject, "FieldsObject must not be null!");

Document mappedFields = mapFieldsToPropertyNames(fieldsObject, entity);
mapMetaAttributes(mappedFields, entity, MetaMapping.FORCE);
return mappedFields;
return mapMetaAttributes(mappedFields, entity, MetaMapping.FORCE);
}

private Document mapFieldsToPropertyNames(Document fields, @Nullable MongoPersistentEntity<?> entity) {

if (fields.isEmpty()) {
return new Document();
return BsonUtils.EMPTY_DOCUMENT;

}
Document target = new Document();
for (Map.Entry<String, Object> entry : BsonUtils.asMap(filterUnwrappedObjects(fields, entity)).entrySet()) {

Field field = createPropertyField(entity, entry.getKey(), mappingContext);
BsonUtils.asMap(filterUnwrappedObjects(fields, entity)).forEach((k, v) -> {

Field field = createPropertyField(entity, k, mappingContext);
if (field.getProperty() != null && field.getProperty().isUnwrapped()) {
continue;
return;
}

target.put(field.getMappedKey(), entry.getValue());
}
target.put(field.getMappedKey(), v);
});

return target;
}

private void mapMetaAttributes(Document source, @Nullable MongoPersistentEntity<?> entity, MetaMapping metaMapping) {
private Document mapMetaAttributes(Document source, @Nullable MongoPersistentEntity<?> entity,
MetaMapping metaMapping) {

if (entity == null) {
return;
return source;
}

if (entity.hasTextScoreProperty() && !MetaMapping.IGNORE.equals(metaMapping)) {

if (source == BsonUtils.EMPTY_DOCUMENT) {
source = new Document();
}

MongoPersistentProperty textScoreProperty = entity.getTextScoreProperty();
if (MetaMapping.FORCE.equals(metaMapping)
|| (MetaMapping.WHEN_PRESENT.equals(metaMapping) && source.containsKey(textScoreProperty.getFieldName()))) {
source.putAll(getMappedTextScoreField(textScoreProperty));
}
}

return source;
}

private Document filterUnwrappedObjects(Document fieldsObject, @Nullable MongoPersistentEntity<?> entity) {
Expand Down Expand Up @@ -679,7 +687,7 @@ protected final Entry<String, Object> createMapEntry(Field field, @Nullable Obje
private Entry<String, Object> createMapEntry(String key, @Nullable Object value) {

Assert.hasText(key, "Key must not be null or empty!");
return Collections.singletonMap(key, value).entrySet().iterator().next();
return new AbstractMap.SimpleEntry<>(key, value);
}

private Object createReferenceFor(Object source, MongoPersistentProperty property) {
Expand Down Expand Up @@ -733,13 +741,13 @@ protected boolean isNestedKeyword(@Nullable Object candidate) {
return false;
}

Set<String> keys = BsonUtils.asMap((Bson) candidate).keySet();
Map<String, Object> map = BsonUtils.asMap((Bson) candidate);

if (keys.size() != 1) {
if (map.size() != 1) {
return false;
}

return isKeyword(keys.iterator().next());
return isKeyword(map.entrySet().iterator().next().getKey());
}

/**
Expand Down Expand Up @@ -823,11 +831,14 @@ public Keyword(Bson source, String key) {

public Keyword(Bson bson) {

Set<String> keys = BsonUtils.asMap(bson).keySet();
Assert.isTrue(keys.size() == 1, "Can only use a single value Document!");
Map<String, Object> map = BsonUtils.asMap(bson);
Assert.isTrue(map.size() == 1, "Can only use a single value Document!");

Set<Entry<String, Object>> entries = map.entrySet();
Entry<String, Object> entry = entries.iterator().next();

this.key = keys.iterator().next();
this.value = BsonUtils.get(bson, key);
this.key = entry.getKey();
this.value = entry.getValue();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ private enum MetaKey {
}
}

private final Map<String, Object> values = new LinkedHashMap<>(2);
private final Set<CursorOption> flags = new LinkedHashSet<>();
private Map<String, Object> values = Collections.emptyMap();
private Set<CursorOption> flags = Collections.emptySet();
private Integer cursorBatchSize;
private Boolean allowDiskUse;

Expand All @@ -63,8 +63,9 @@ public Meta() {}
* @param source
*/
Meta(Meta source) {
this.values.putAll(source.values);
this.flags.addAll(source.flags);

this.values = new LinkedHashMap<>(source.values);
this.flags = new LinkedHashSet<>(source.flags);
this.cursorBatchSize = source.cursorBatchSize;
this.allowDiskUse = source.allowDiskUse;
}
Expand Down Expand Up @@ -158,6 +159,11 @@ public void setCursorBatchSize(int cursorBatchSize) {
public boolean addFlag(CursorOption option) {

Assert.notNull(option, "CursorOption must not be null!");

if (this.flags == Collections.EMPTY_SET) {
this.flags = new LinkedHashSet<>(2);
}

return this.flags.add(option);
}

Expand Down Expand Up @@ -220,6 +226,10 @@ void setValue(String key, @Nullable Object value) {

Assert.hasText(key, "Meta key must not be 'null' or blank.");

if (values == Collections.EMPTY_MAP) {
values = new LinkedHashMap<>(2);
}

if (value == null || (value instanceof String && !StringUtils.hasText((String) value))) {
this.values.remove(key);
}
Expand Down
Loading