From 781717faa81fb12db88b8842fae19dff05f7d26e Mon Sep 17 00:00:00 2001 From: Laszlo Csontos Date: Wed, 22 Feb 2017 06:51:14 +0100 Subject: [PATCH] DATAMONGO-1617 - BeforeConvertEvent is now emitted before updatable idendifier assertion. We now make sure the BeforeConvertEvent is published before we check for identifier types that can potentially be auto-generated. That allows the event listeners to populate identifiers. Previously the identifier check kicked in before that and thus caused the listener not being able to populate the property. Original pull request: #443. --- .../data/mongodb/core/MongoTemplate.java | 9 ++- .../data/mongodb/core/MongoTemplateTests.java | 57 ++++++++++++++++++- .../core/PersonWithIdPropertyOfTypeUUID.java | 57 +++++++++++++++++++ 3 files changed, 116 insertions(+), 7 deletions(-) create mode 100644 spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/PersonWithIdPropertyOfTypeUUID.java diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java index 23ae2b1f9..0c6577be8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java @@ -143,6 +143,7 @@ import com.mongodb.util.JSONParseException; * @author Doménique Tilleuil * @author Niko Schmuck * @author Mark Paluch + * @author Laszlo Csontos */ @SuppressWarnings("deprecation") public class MongoTemplate implements MongoOperations, ApplicationContextAware, IndexOperationsProvider { @@ -832,12 +833,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, protected void doInsert(String collectionName, T objectToSave, MongoWriter writer) { + maybeEmitEvent(new BeforeConvertEvent(objectToSave, collectionName)); assertUpdateableIdIfNotSet(objectToSave); initializeVersionProperty(objectToSave); - maybeEmitEvent(new BeforeConvertEvent(objectToSave, collectionName)); - Document dbDoc = toDocument(objectToSave, writer); maybeEmitEvent(new BeforeSaveEvent(objectToSave, dbDoc, collectionName)); @@ -998,6 +998,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, doInsert(collectionName, objectToSave, this.mongoConverter); } else { + maybeEmitEvent(new BeforeConvertEvent(objectToSave, collectionName)); assertUpdateableIdIfNotSet(objectToSave); // Create query for entity with the id and old version @@ -1009,7 +1010,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, Document document = new Document(); - maybeEmitEvent(new BeforeConvertEvent(objectToSave, collectionName)); this.mongoConverter.write(objectToSave, document); maybeEmitEvent(new BeforeSaveEvent(objectToSave, document, collectionName)); @@ -1028,9 +1028,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, protected void doSave(String collectionName, T objectToSave, MongoWriter writer) { - assertUpdateableIdIfNotSet(objectToSave); - maybeEmitEvent(new BeforeConvertEvent(objectToSave, collectionName)); + assertUpdateableIdIfNotSet(objectToSave); Document dbDoc = toDocument(objectToSave, writer); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java index fc5ee345b..5ebb9f1eb 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java @@ -82,6 +82,7 @@ import org.springframework.data.mongodb.core.index.IndexInfo; import org.springframework.data.mongodb.core.mapping.Field; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener; +import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent; import org.springframework.data.mongodb.core.mapping.event.BeforeSaveEvent; import org.springframework.data.mongodb.core.query.BasicQuery; import org.springframework.data.mongodb.core.query.Criteria; @@ -118,6 +119,7 @@ import com.mongodb.client.result.UpdateResult; * @author Komi Innocent * @author Christoph Strobl * @author Mark Paluch + * @author Laszlo Csontos */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:infrastructure.xml") @@ -132,13 +134,19 @@ public class MongoTemplateTests { @Autowired MongoTemplate template; @Autowired MongoDbFactory factory; - @Autowired ConfigurableApplicationContext context; + ConfigurableApplicationContext context; MongoTemplate mappingTemplate; org.springframework.data.util.Version mongoVersion; @Rule public ExpectedException thrown = ExpectedException.none(); + @Autowired + public void setApplicationContext(ConfigurableApplicationContext context) { + context.addApplicationListener(new PersonWithIdPropertyOfTypeUUIDListener()); + this.context = context; + } + @Autowired public void setMongo(Mongo mongo) throws Exception { @@ -150,7 +158,8 @@ public class MongoTemplateTests { PersonWith_idPropertyOfTypeString.class, PersonWithIdPropertyOfTypeObjectId.class, PersonWithIdPropertyOfTypeString.class, PersonWithIdPropertyOfTypeInteger.class, PersonWithIdPropertyOfTypeBigInteger.class, PersonWithIdPropertyOfPrimitiveInt.class, - PersonWithIdPropertyOfTypeLong.class, PersonWithIdPropertyOfPrimitiveLong.class))); + PersonWithIdPropertyOfTypeLong.class, PersonWithIdPropertyOfPrimitiveLong.class, + PersonWithIdPropertyOfTypeUUID.class))); mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder()); mappingContext.initialize(); @@ -193,6 +202,7 @@ public class MongoTemplateTests { template.dropCollection(PersonWithIdPropertyOfPrimitiveInt.class); template.dropCollection(PersonWithIdPropertyOfTypeLong.class); template.dropCollection(PersonWithIdPropertyOfPrimitiveLong.class); + template.dropCollection(PersonWithIdPropertyOfTypeUUID.class); template.dropCollection(PersonWithVersionPropertyOfTypeInteger.class); template.dropCollection(TestClass.class); template.dropCollection(Sample.class); @@ -627,6 +637,23 @@ public class MongoTemplateTests { assertThat(p12q, notNullValue()); assertThat(p12q.getId(), is(p12.getId())); checkCollectionContents(PersonWithIdPropertyOfPrimitiveLong.class, 1); + + // DATAMONGO-1617 + // UUID id - provided + PersonWithIdPropertyOfTypeUUID p13 = new PersonWithIdPropertyOfTypeUUID(); + p13.setFirstName("Sven_10"); + p13.setAge(22); + p13.setId(UUID.randomUUID()); + // insert + mongoTemplate.insert(p13); + // also try save + mongoTemplate.save(p13); + assertThat(p13.getId(), notNullValue()); + PersonWithIdPropertyOfTypeUUID p13q = mongoTemplate.findOne(new Query(where("id").in(p13.getId())), + PersonWithIdPropertyOfTypeUUID.class); + assertThat(p13q, notNullValue()); + assertThat(p13q.getId(), is(p13.getId())); + checkCollectionContents(PersonWithIdPropertyOfTypeUUID.class, 1); } private void checkCollectionContents(Class entityClass, int count) { @@ -1427,6 +1454,17 @@ public class MongoTemplateTests { template.insert(document, template.determineCollectionName(PersonWithVersionPropertyOfTypeInteger.class)); } + @Test // DATAMONGO-1617 + public void doesNotFailOnInsertForEntityWithNonAutogeneratableId() { + + PersonWithIdPropertyOfTypeUUID person = new PersonWithIdPropertyOfTypeUUID(); + person.setFirstName("Laszlo"); + person.setAge(33); + + template.insert(person); + assertThat(person.getId(), is(notNullValue())); + } + @Test // DATAMONGO-539 public void removesObjectFromExplicitCollection() { @@ -3570,4 +3608,19 @@ public class MongoTemplateTests { @Id String id; Object value; } + + static class PersonWithIdPropertyOfTypeUUIDListener extends AbstractMongoEventListener { + + @Override + public void onBeforeConvert(BeforeConvertEvent event) { + PersonWithIdPropertyOfTypeUUID person = event.getSource(); + + if (person.getId() != null) { + return; + } + + person.setId(UUID.randomUUID()); + } + + } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/PersonWithIdPropertyOfTypeUUID.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/PersonWithIdPropertyOfTypeUUID.java new file mode 100644 index 000000000..46a5a6f87 --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/PersonWithIdPropertyOfTypeUUID.java @@ -0,0 +1,57 @@ +/* + * Copyright 2010-2017 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; + +import java.util.UUID; + +public class PersonWithIdPropertyOfTypeUUID { + + private UUID id; + + private String firstName; + + private int age; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + @Override + public String toString() { + return "PersonWithIdPropertyOfTypeUUID [id=" + id + ", firstName=" + firstName + ", age=" + age + "]"; + } + +}