Skip to content

Fix id conversion for fields of complex id. #4719

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 4 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>4.4.0-SNAPSHOT</version>
<version>4.4.x-GH-4707-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>4.4.0-SNAPSHOT</version>
<version>4.4.x-GH-4707-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 @@ -15,7 +15,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>4.4.0-SNAPSHOT</version>
<version>4.4.x-GH-4707-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 @@ -13,7 +13,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>4.4.0-SNAPSHOT</version>
<version>4.4.x-GH-4707-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1603,9 +1603,7 @@ protected Object saveDocument(String collectionName, Document dbDoc, Class<?> en
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
UpdateContext updateContext = queryOperations.replaceSingleContext(mapped, true);
Document replacement = updateContext.getMappedUpdate(entity);

Document filter = updateContext.getMappedQuery(entity);

Document filter = updateContext.getReplacementQuery();
if (updateContext.requiresShardKey(filter, entity)) {

if (entity.getShardKey().isImmutable()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ private Document evaluateFields(@Nullable MongoPersistentEntity<?> entity) {

for (Entry<String, Object> entry : fields.entrySet()) {

if (entry.getValue()instanceof MongoExpression mongoExpression) {
if (entry.getValue() instanceof MongoExpression mongoExpression) {

AggregationOperationContext ctx = entity == null ? Aggregation.DEFAULT_CONTEXT
: new RelaxedTypeBasedAggregationOperationContext(entity.getType(), mappingContext, queryMapper);
Expand Down Expand Up @@ -809,13 +809,23 @@ ReplaceOptions getReplaceOptions(@Nullable Class<?> domainType, @Nullable Consum

@Override
<T> Document getMappedQuery(@Nullable MongoPersistentEntity<T> domainType) {
return applyIsolation(super.getMappedQuery(domainType));
}

Document mappedQuery = super.getMappedQuery(domainType);
/**
* A replacement query that is derived from the already {@link MappedDocument}.
*
* @return
*/
Document getReplacementQuery() {
return applyIsolation(getQueryObject());
}

private Document applyIsolation(Document mappedQuery) {
if (multi && update != null && update.isIsolated() && !mappedQuery.containsKey("$isolated")) {
mappedQuery = new Document(mappedQuery);
mappedQuery.put("$isolated", 1);
}

return mappedQuery;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1649,7 +1649,7 @@ protected Mono<Object> saveDocument(String collectionName, Document document, Cl

MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass);
UpdateContext updateContext = queryOperations.replaceSingleContext(mapped, true);
Document filter = updateContext.getMappedQuery(entity);
Document filter = updateContext.getReplacementQuery();
Document replacement = updateContext.getMappedUpdate(entity);

Mono<Document> deferredFilter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,12 @@ private Object convertIdField(Field documentField, Object source) {
} else if (isKeyword(key)) {
resultDbo.put(key, convertIdField(documentField, entry.getValue()));
} else {
resultDbo.put(key, getMappedValue(documentField, entry.getValue()));
if(documentField.getProperty() != null && documentField.getProperty().isEntity()) {
Field propertyField = createPropertyField(documentField.getPropertyEntity(), key, mappingContext);
resultDbo.put(key, getMappedValue(propertyField, entry.getValue()));
} else {
resultDbo.put(key, getMappedValue(documentField, entry.getValue()));
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1409,18 +1409,21 @@ public void executesQueryWithNegatedRegexCorrectly() {
assertThat(result.get(0).field).isEqualTo("Beauford");
}

@Test // DATAMONGO-447
@Test // DATAMONGO-447, GH-4707
public void storesAndRemovesTypeWithComplexId() {

MyId id = new MyId();
id.id = Instant.now().minusSeconds(2);
id.first = "foo";
id.second = "bar";
id.time = Instant.now().minusSeconds(3);

TypeWithMyId source = new TypeWithMyId();
source.id = id;

template.save(source);
template.remove(query(where("id").is(id)), TypeWithMyId.class);
assertThat(template.remove(query(where("id").is(id)), TypeWithMyId.class)).extracting(DeleteResult::getDeletedCount)
.isEqualTo(1L);
}

@Test // DATAMONGO-506
Expand Down Expand Up @@ -2554,6 +2557,29 @@ public void findAndReplaceShouldProjectReturnedObjectCorrectly() {
assertThat(projection.getName()).isEqualTo("Walter");
}

@Test // GH-4707
public void findAndReplaceUpsertsObjectWithComplexId() {

MyId id = new MyId();
id.id = Instant.now().minusSeconds(2);
id.first = "foo";
id.second = "bar";
id.time = Instant.now().minusSeconds(3);

TypeWithMyId replacement = new TypeWithMyId();
replacement.value = "spring";

template.findAndReplace(query(where("id").is(id)), replacement, FindAndReplaceOptions.options().upsert());
template.doInCollection(TypeWithMyId.class, collection -> {

org.bson.Document dbValue = collection.find(new org.bson.Document("_id.first", "foo")).first();

assertThat(dbValue).isNotNull();
assertThat(dbValue.getEmbedded(List.of("_id", "_id"), Object.class)).isInstanceOf(Date.class);
assertThat(dbValue.getEmbedded(List.of("_id", "t"), Object.class)).isInstanceOf(Date.class);
});
}

@Test // GH-4609
public void shouldReadNestedProjection() {

Expand Down Expand Up @@ -4397,11 +4423,15 @@ static class MyId {

String first;
String second;
Instant id;

@Field("t") Instant time;
}

static class TypeWithMyId {

@Id MyId id;
String value;
}

static class Sample {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@
import org.springframework.data.mapping.callback.EntityCallbacks;
import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.util.MongoCompatibilityAdapter;

import com.mongodb.MongoWriteException;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoCollection;
import org.springframework.data.mongodb.util.MongoCompatibilityAdapter;

/**
* A {@link MongoTemplate} with configuration hooks and extension suitable for tests.
Expand Down Expand Up @@ -147,4 +147,11 @@ public void dropIndexes(Class<?>... entities) {
getCollection(getCollectionName(entity)).dropIndexes();
}
}

public void doInCollection(Class<?> entityClass, Consumer<MongoCollection<Document>> callback) {
execute(entityClass, (collection -> {
callback.accept(collection);
return null;
}));
}
}