From 593c5366fa93463a4583fe1d78de9c7808dfa38d 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 f8708cb38..8cea8fe3b 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 @@ -141,6 +141,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 { @@ -844,12 +845,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)); - DBObject dbDoc = toDbObject(objectToSave, writer); maybeEmitEvent(new BeforeSaveEvent(objectToSave, dbDoc, collectionName)); @@ -1001,6 +1001,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 @@ -1012,7 +1013,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware { BasicDBObject dbObject = new BasicDBObject(); - maybeEmitEvent(new BeforeConvertEvent(objectToSave, collectionName)); this.mongoConverter.write(objectToSave, dbObject); maybeEmitEvent(new BeforeSaveEvent(objectToSave, dbObject, collectionName)); @@ -1025,9 +1025,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); DBObject dbDoc = toDbObject(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 a281b9d62..b59328f3a 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; @@ -119,6 +120,7 @@ import com.mongodb.WriteResult; * @author Komi Innocent * @author Christoph Strobl * @author Mark Paluch + * @author Laszlo Csontos */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:infrastructure.xml") @@ -134,13 +136,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 { @@ -152,7 +160,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(); @@ -195,6 +204,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); @@ -632,6 +642,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) { @@ -1429,6 +1456,17 @@ public class MongoTemplateTests { template.insert(dbObject, 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() { @@ -3545,4 +3583,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 + "]"; + } + +}