diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java index 34c08144a..419915dac 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java @@ -30,7 +30,6 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; -import org.springframework.context.ApplicationEventPublisher; import org.springframework.core.CollectionFactory; import org.springframework.core.convert.ConversionException; import org.springframework.core.convert.ConversionService; @@ -57,6 +56,7 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.mapping.event.AfterConvertEvent; import org.springframework.data.mongodb.core.mapping.event.AfterLoadEvent; +import org.springframework.data.mongodb.core.mapping.event.MongoMappingEvent; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; import org.springframework.expression.spel.standard.SpelExpressionParser; @@ -872,7 +872,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @Override public Object getValueInternal(MongoPersistentProperty prop, DBObject dbo, SpELExpressionEvaluator evaluator, ObjectPath path) { - return new MongoDbPropertyValueProvider(dbo, evaluator, path, false).getPropertyValue(prop); + return new MongoDbPropertyValueProvider(dbo, evaluator, path).getPropertyValue(prop); } /** @@ -1116,7 +1116,6 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App private final DBObjectAccessor source; private final SpELExpressionEvaluator evaluator; private final ObjectPath path; - private final boolean ignoreLazyDBRefProperties; /** * Creates a new {@link MongoDbPropertyValueProvider} for the given source, {@link SpELExpressionEvaluator} and @@ -1127,18 +1126,13 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App * @param path can be {@literal null}. */ public MongoDbPropertyValueProvider(DBObject source, SpELExpressionEvaluator evaluator, ObjectPath path) { - this(source, evaluator, path, true); // ignoring by default - } - MongoDbPropertyValueProvider(DBObject source, SpELExpressionEvaluator evaluator, ObjectPath path, - boolean ignoreLazyDBRefProperties) { Assert.notNull(source); Assert.notNull(evaluator); this.source = new DBObjectAccessor(source); this.evaluator = evaluator; this.path = path; - this.ignoreLazyDBRefProperties = ignoreLazyDBRefProperties; } /* @@ -1153,12 +1147,6 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App if (value == null) { return null; } - if (this.ignoreLazyDBRefProperties && property.isDbReference() && property.getDBRef().lazy()) { // lazy DBRef, - // BasicDBList are - // resolved later - // by default - return null; - } return readValue(value, property.getTypeInformation(), path); } @@ -1220,24 +1208,39 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @SuppressWarnings("unchecked") private T potentiallyReadOrResolveDbRef(DBRef dbref, TypeInformation type, ObjectPath path, Class rawType) { + if (rawType.equals(DBRef.class)) { return (T) dbref; } + Object object = dbref == null ? null : path.getPathItem(dbref.getId(), dbref.getCollectionName()); return (T) (object != null ? object : readAndConvertDBRef(dbref, type, path, rawType)); } - private T readAndConvertDBRef(DBRef dbref, TypeInformation type, ObjectPath path, Class rawType) { - DBObject readRef = readRef(dbref); + @SuppressWarnings("unchecked") + private T readAndConvertDBRef(DBRef dbref, TypeInformation type, ObjectPath path, final Class rawType) { + + final DBObject readRef = readRef(dbref); final String collectionName = dbref.getCollectionName(); - if (canPublishEvent()) - ((ApplicationEventPublisher) this.applicationContext) - .publishEvent(new AfterLoadEvent(readRef, (Class) rawType, collectionName)); - T t = (T) read(type, readRef, path); - if (canPublishEvent()) - ((ApplicationEventPublisher) this.applicationContext) - .publishEvent(new AfterConvertEvent(readRef, t, collectionName)); - return t; + + if (readRef != null) { + maybeEmitEvent(new AfterLoadEvent(readRef, (Class) rawType, collectionName)); + } + + final T target = (T) read(type, readRef, path); + + if (target != null) { + maybeEmitEvent(new AfterConvertEvent(readRef, target, collectionName)); + } + + return target; + } + + private void maybeEmitEvent(MongoMappingEvent event) { + + if (canPublishEvent()) { + this.applicationContext.publishEvent(event); + } } private boolean canPublishEvent() { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTests.java index cefd922b0..c600911ee 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2015 by the original author(s). + * Copyright (c) 2011-2016 by the original author(s). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,29 +15,39 @@ */ package org.springframework.data.mongodb.core.mapping.event; -import com.mongodb.DB; -import com.mongodb.DBObject; -import com.mongodb.Mongo; -import com.mongodb.MongoClient; -import com.mongodb.WriteConcern; +import static org.hamcrest.collection.IsCollectionWithSize.*; +import static org.hamcrest.core.Is.*; +import static org.hamcrest.core.IsEqual.*; +import static org.junit.Assert.*; +import static org.springframework.data.mongodb.core.query.Criteria.*; +import static org.springframework.data.mongodb.core.query.Query.*; + import java.net.UnknownHostException; import java.util.Arrays; -import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; -import static org.hamcrest.core.Is.is; + import org.junit.After; import org.junit.Assert; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.aggregation.Aggregation; +import org.springframework.data.mongodb.core.mapping.DBRef; +import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.PersonPojoStringId; -import static org.springframework.data.mongodb.core.query.Criteria.where; -import static org.springframework.data.mongodb.core.query.Query.query; + +import com.mongodb.DB; +import com.mongodb.DBObject; +import com.mongodb.Mongo; +import com.mongodb.MongoClient; +import com.mongodb.WriteConcern; + +import lombok.Data; /** * Integration test for Mapping Events. @@ -48,14 +58,16 @@ import static org.springframework.data.mongodb.core.query.Query.query; */ public class ApplicationContextEventTests { - private static final String COLLECTION_NAME = "personPojoStringId"; - private static final String ROOT_COLLECTION_NAME = "root"; - private static final String RELATED_COLLECTION_NAME = "related"; + private static final String COLLECTION_NAME = "personPojoStringId"; + private static final String ROOT_COLLECTION_NAME = "root"; + private static final String RELATED_COLLECTION_NAME = "related"; - private final String[] collectionsToDrop = new String[] { COLLECTION_NAME, ROOT_COLLECTION_NAME, RELATED_COLLECTION_NAME }; + private final String[] collectionsToDrop = new String[] { COLLECTION_NAME, ROOT_COLLECTION_NAME, + RELATED_COLLECTION_NAME }; private ApplicationContext applicationContext; private MongoTemplate template; + private SimpleMappingEventListener simpleMappingEventListener; @Before public void setUp() throws Exception { @@ -63,6 +75,7 @@ public class ApplicationContextEventTests { applicationContext = new AnnotationConfigApplicationContext(ApplicationContextEventTestsAppConfig.class); template = applicationContext.getBean(MongoTemplate.class); template.setWriteConcern(WriteConcern.FSYNC_SAFE); + simpleMappingEventListener = applicationContext.getBean(SimpleMappingEventListener.class); } @After @@ -82,10 +95,9 @@ public class ApplicationContextEventTests { @Test @SuppressWarnings("unchecked") public void beforeSaveEvent() { + PersonBeforeSaveListener personBeforeSaveListener = applicationContext.getBean(PersonBeforeSaveListener.class); AfterSaveListener afterSaveListener = applicationContext.getBean(AfterSaveListener.class); - SimpleMappingEventListener simpleMappingEventListener = applicationContext - .getBean(SimpleMappingEventListener.class); assertEquals(0, personBeforeSaveListener.seenEvents.size()); assertEquals(0, afterSaveListener.seenEvents.size()); @@ -129,9 +141,6 @@ public class ApplicationContextEventTests { @Test public void loadAndConvertEvents() { - SimpleMappingEventListener simpleMappingEventListener = applicationContext - .getBean(SimpleMappingEventListener.class); - PersonPojoStringId entity = new PersonPojoStringId("1", "Text"); template.insert(entity); @@ -153,9 +162,6 @@ public class ApplicationContextEventTests { @Test public void loadEventsOnAggregation() { - SimpleMappingEventListener simpleMappingEventListener = applicationContext - .getBean(SimpleMappingEventListener.class); - template.insert(new PersonPojoStringId("1", "Text")); template.aggregate(Aggregation.newAggregation(Aggregation.project("text")), PersonPojoStringId.class, @@ -177,9 +183,6 @@ public class ApplicationContextEventTests { @Test public void deleteEvents() { - SimpleMappingEventListener simpleMappingEventListener = applicationContext - .getBean(SimpleMappingEventListener.class); - PersonPojoStringId entity = new PersonPojoStringId("1", "Text"); template.insert(entity); @@ -191,151 +194,232 @@ public class ApplicationContextEventTests { assertThat(simpleMappingEventListener.onAfterDeleteEvents.size(), is(1)); assertThat(simpleMappingEventListener.onAfterDeleteEvents.get(0).getCollectionName(), is(COLLECTION_NAME)); } - - /** - * DATAMONGO-1271 DATAMONGO-1287 - */ - @Test - public void loadAndConvertEventsInInnerSimpleDBRef () throws Exception { - ParentMappingEventListener simpleMappingEventListener = applicationContext.getBean(ParentMappingEventListener.class); - Related embed = new Related(1L, "embed desc"); - Related ref1 = new Related(2L, "related desc1"); - Related ref2 = new Related(3L, "related desc2"); - template.insert(embed); - template.insert(ref1); - template.insert(ref2); - - Root root = new Root(1L, embed, ref1, ref2, null, null, null, null); - template.insert(root); - - assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(0)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(0)); - - // initially fetching ROOT document and also eagerly fetching 1 DBRef - Root rootR = template.findOne(query(where("id").is(root.getId())), Root.class); - assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(2)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(2)); - - // checking that no event is fired because those documents were previously eagerly fetched - rootR.getRef().getDescription(); - rootR.getEmbed().getDescription(); - assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(2)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(2)); - // checking that accessing lazy DBRef fires 1 more event of each type - rootR.getLazyRef().getDescription(); - assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(3)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(3)); - - // checking collectionNames fired - assertThat(simpleMappingEventListener.onAfterLoadEvents.get(0).getCollectionName(), is(ROOT_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.get(0).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterLoadEvents.get(1).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.get(1).getCollectionName(), is(ROOT_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterLoadEvents.get(2).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.get(2).getCollectionName(), is(RELATED_COLLECTION_NAME)); - } - - /** - * DATAMONGO-1271 DATAMONGO-1287 - */ - @Test - public void loadAndConvertEventsInInnerListDBRef() throws Exception { - ParentMappingEventListener simpleMappingEventListener = applicationContext.getBean(ParentMappingEventListener.class); - Related embed = new Related(1L, "embed desc"); - Related ref1 = new Related(2L, "related desc1"); - Related ref2 = new Related(3L, "related desc2"); - template.insert(embed); - template.insert(ref1); - template.insert(ref2); - - Root root = new Root(1L, embed, null, null, Arrays.asList(ref1, ref2), Arrays.asList(ref1, ref2), null, null); - template.insert(root); - assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(0)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(0)); - - // initially fetching ROOT document and also eagerly fetching 2 DBRef - Root rootR = template.findOne(query(where("id").is(root.getId())), Root.class); - assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(3)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(3)); - - // checking that no event is fired because those documents were previously eagerly fetched - rootR.getListRef().get(0).getDescription(); - rootR.getListRef().get(1).getDescription(); - assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(3)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(3)); - - // fetching lazily dbref - rootR.getListLazy().get(0).getDescription(); - rootR.getListLazy().get(1).getDescription(); - assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(5)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(5)); - - // checking collectionNames fired - assertThat(simpleMappingEventListener.onAfterLoadEvents.get(0).getCollectionName(), is(ROOT_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.get(0).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterLoadEvents.get(1).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.get(1).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterLoadEvents.get(2).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.get(2).getCollectionName(), is(ROOT_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterLoadEvents.get(3).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.get(3).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterLoadEvents.get(4).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.get(4).getCollectionName(), is(RELATED_COLLECTION_NAME)); - } - - /** - * DATAMONGO-1271 DATAMONGO-1287 - */ - @Test - public void loadAndConvertEventsInInnerMapDBRef() throws Exception { - ParentMappingEventListener simpleMappingEventListener = applicationContext.getBean(ParentMappingEventListener.class); - Related embed = new Related(1L, "embed desc"); - Related ref1 = new Related(2L, "related desc1"); - Related ref2 = new Related(3L, "related desc2"); - template.insert(embed); - template.insert(ref1); - template.insert(ref2); - - Map mapRef = new HashMap(); - mapRef.put("1", ref1); - mapRef.put("2", ref2); - Map mapLazy = new HashMap(); - mapLazy.put("1", ref1); - mapLazy.put("2", ref2); - - Root root = new Root(1L, embed, null, null, null, null, mapRef, mapLazy); - template.insert(root); - assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(0)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(0)); - - // initially fetching ROOT document and also eagerly fetching 2 DBRef (eager map) - Root rootR = template.findOne(query(where("id").is(root.getId())), Root.class); - assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(3)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(3)); - - // checking that accessing eagerly fetched map does not fire any new event - Assert.assertEquals(0, rootR.getMapRef().keySet().stream().filter(key -> rootR.getMapRef().get(key).getDescription() == null).count()); - assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(3)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(3)); - // accessing lazy map of dbref - Assert.assertEquals(0, rootR.getMapLazy().keySet().stream().filter(key -> rootR.getMapLazy().get(key).getDescription() == null).count()); - assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(5)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(5)); - - // checking collectionNames fired - assertThat(simpleMappingEventListener.onAfterLoadEvents.get(0).getCollectionName(), is(ROOT_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.get(0).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterLoadEvents.get(1).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.get(1).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterLoadEvents.get(2).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.get(2).getCollectionName(), is(ROOT_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterLoadEvents.get(3).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.get(3).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterLoadEvents.get(4).getCollectionName(), is(RELATED_COLLECTION_NAME)); - assertThat(simpleMappingEventListener.onAfterConvertEvents.get(4).getCollectionName(), is(RELATED_COLLECTION_NAME)); - } + + /** + * @see DATAMONGO-1271 + */ + @Test + public void publishesAfterLoadAndAfterConvertEventsForDBRef() throws Exception { + + Related ref1 = new Related(2L, "related desc1"); + + template.insert(ref1); + + Root source = new Root(); + source.id = 1L; + source.reference = ref1; + + template.insert(source); + + template.findOne(query(where("id").is(source.getId())), Root.class); + + assertThat(simpleMappingEventListener.onAfterLoadEvents, hasSize(2)); + assertThat(simpleMappingEventListener.onAfterLoadEvents.get(0).getCollectionName(), + is(equalTo(ROOT_COLLECTION_NAME))); + assertThat(simpleMappingEventListener.onAfterLoadEvents.get(1).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + + assertThat(simpleMappingEventListener.onAfterConvertEvents, hasSize(2)); + assertThat(simpleMappingEventListener.onAfterConvertEvents.get(0).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + assertThat(simpleMappingEventListener.onAfterConvertEvents.get(1).getCollectionName(), + is(equalTo(ROOT_COLLECTION_NAME))); + } + + /** + * @see DATAMONGO-1271 + */ + @Test + public void publishesAfterLoadAndAfterConvertEventsForLazyLoadingDBRef() throws Exception { + + Related ref1 = new Related(2L, "related desc1"); + + template.insert(ref1); + + Root source = new Root(); + source.id = 1L; + source.lazyReference = ref1; + + template.insert(source); + + Root target = template.findOne(query(where("id").is(source.getId())), Root.class); + + assertThat(simpleMappingEventListener.onAfterLoadEvents, hasSize(1)); + assertThat(simpleMappingEventListener.onAfterLoadEvents.get(0).getCollectionName(), + is(equalTo(ROOT_COLLECTION_NAME))); + + assertThat(simpleMappingEventListener.onAfterConvertEvents, hasSize(1)); + assertThat(simpleMappingEventListener.onAfterConvertEvents.get(0).getCollectionName(), + is(equalTo(ROOT_COLLECTION_NAME))); + + target.getLazyReference().getDescription(); + + assertThat(simpleMappingEventListener.onAfterLoadEvents, hasSize(2)); + assertThat(simpleMappingEventListener.onAfterLoadEvents.get(1).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + + assertThat(simpleMappingEventListener.onAfterConvertEvents, hasSize(2)); + assertThat(simpleMappingEventListener.onAfterConvertEvents.get(1).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + } + + /** + * @see DATAMONGO-1271 + */ + @Test + public void publishesAfterLoadAndAfterConvertEventsForListOfDBRef() throws Exception { + + List references = Arrays.asList(new Related(20L, "ref 1"), new Related(30L, "ref 2")); + + template.insert(references, Related.class); + + Root source = new Root(); + source.id = 1L; + source.listOfReferences = references; + + template.insert(source); + + template.findOne(query(where("id").is(source.getId())), Root.class); + + assertThat(simpleMappingEventListener.onAfterLoadEvents, hasSize(3)); + assertThat(simpleMappingEventListener.onAfterLoadEvents.get(0).getCollectionName(), + is(equalTo(ROOT_COLLECTION_NAME))); + assertThat(simpleMappingEventListener.onAfterLoadEvents.get(1).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + assertThat(simpleMappingEventListener.onAfterLoadEvents.get(2).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + + assertThat(simpleMappingEventListener.onAfterConvertEvents, hasSize(3)); + assertThat(simpleMappingEventListener.onAfterConvertEvents.get(0).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + assertThat(simpleMappingEventListener.onAfterConvertEvents.get(1).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + assertThat(simpleMappingEventListener.onAfterConvertEvents.get(2).getCollectionName(), + is(equalTo(ROOT_COLLECTION_NAME))); + } + + /** + * @see DATAMONGO-1271 + */ + @Test + public void publishesAfterLoadAndAfterConvertEventsForLazyLoadingListOfDBRef() throws Exception { + + List references = Arrays.asList(new Related(20L, "ref 1"), new Related(30L, "ref 2")); + + template.insert(references, Related.class); + + Root source = new Root(); + source.id = 1L; + source.lazyListOfReferences = references; + + template.insert(source); + + Root target = template.findOne(query(where("id").is(source.getId())), Root.class); + + assertThat(simpleMappingEventListener.onAfterLoadEvents, hasSize(1)); + assertThat(simpleMappingEventListener.onAfterLoadEvents.get(0).getCollectionName(), + is(equalTo(ROOT_COLLECTION_NAME))); + assertThat(simpleMappingEventListener.onAfterConvertEvents, hasSize(1)); + assertThat(simpleMappingEventListener.onAfterConvertEvents.get(0).getCollectionName(), + is(equalTo(ROOT_COLLECTION_NAME))); + + target.getLazyListOfReferences().size(); + + assertThat(simpleMappingEventListener.onAfterLoadEvents, hasSize(3)); + assertThat(simpleMappingEventListener.onAfterConvertEvents, hasSize(3)); + + assertThat(simpleMappingEventListener.onAfterLoadEvents.get(1).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + assertThat(simpleMappingEventListener.onAfterLoadEvents.get(2).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + assertThat(simpleMappingEventListener.onAfterConvertEvents.get(1).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + assertThat(simpleMappingEventListener.onAfterConvertEvents.get(2).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + } + + /** + * @see DATAMONGO-1271 + */ + @Test + public void publishesAfterLoadAndAfterConvertEventsForMapOfDBRef() throws Exception { + + Map references = new LinkedHashMap(); + references.put("ref-1", new Related(20L, "ref 1")); + references.put("ref-2", new Related(30L, "ref 2")); + + template.insert(references.values(), Related.class); + + Root source = new Root(); + source.id = 1L; + source.mapOfReferences = references; + + template.insert(source); + + template.findOne(query(where("id").is(source.getId())), Root.class); + + assertThat(simpleMappingEventListener.onAfterLoadEvents, hasSize(3)); + assertThat(simpleMappingEventListener.onAfterLoadEvents.get(0).getCollectionName(), + is(equalTo(ROOT_COLLECTION_NAME))); + assertThat(simpleMappingEventListener.onAfterLoadEvents.get(1).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + assertThat(simpleMappingEventListener.onAfterLoadEvents.get(2).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + + assertThat(simpleMappingEventListener.onAfterConvertEvents, hasSize(3)); + assertThat(simpleMappingEventListener.onAfterConvertEvents.get(0).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + assertThat(simpleMappingEventListener.onAfterConvertEvents.get(1).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + assertThat(simpleMappingEventListener.onAfterConvertEvents.get(2).getCollectionName(), + is(equalTo(ROOT_COLLECTION_NAME))); + } + + /** + * @see DATAMONGO-1271 + */ + @Test + public void publishesAfterLoadAndAfterConvertEventsForLazyLoadingMapOfDBRef() throws Exception { + + Map references = new LinkedHashMap(); + references.put("ref-1", new Related(20L, "ref 1")); + references.put("ref-2", new Related(30L, "ref 2")); + + template.insert(references.values(), Related.class); + + Root source = new Root(); + source.id = 1L; + source.lazyMapOfReferences = references; + + template.insert(source); + + Root target = template.findOne(query(where("id").is(source.getId())), Root.class); + + assertThat(simpleMappingEventListener.onAfterLoadEvents, hasSize(1)); + assertThat(simpleMappingEventListener.onAfterLoadEvents.get(0).getCollectionName(), + is(equalTo(ROOT_COLLECTION_NAME))); + + assertThat(simpleMappingEventListener.onAfterConvertEvents, hasSize(1)); + assertThat(simpleMappingEventListener.onAfterConvertEvents.get(0).getCollectionName(), + is(equalTo(ROOT_COLLECTION_NAME))); + + target.getLazyMapOfReferences().size(); + + assertThat(simpleMappingEventListener.onAfterLoadEvents, hasSize(3)); + assertThat(simpleMappingEventListener.onAfterLoadEvents.get(1).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + assertThat(simpleMappingEventListener.onAfterLoadEvents.get(2).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + + assertThat(simpleMappingEventListener.onAfterConvertEvents, hasSize(3)); + assertThat(simpleMappingEventListener.onAfterConvertEvents.get(1).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + assertThat(simpleMappingEventListener.onAfterConvertEvents.get(2).getCollectionName(), + is(equalTo(RELATED_COLLECTION_NAME))); + } private void comparePersonAndDbo(PersonPojoStringId p, PersonPojoStringId p2, DBObject dbo) { + assertEquals(p.getId(), p2.getId()); assertEquals(p.getText(), p2.getText()); @@ -343,4 +427,28 @@ public class ApplicationContextEventTests { assertEquals("1", dbo.get("_id")); assertEquals("Text", dbo.get("text")); } + + @Data + @Document + public static class Root { + + @Id Long id; + + @DBRef Related reference; + @DBRef(lazy = true) Related lazyReference; + + @DBRef List listOfReferences; + @DBRef(lazy = true) List lazyListOfReferences; + + @DBRef Map mapOfReferences; + @DBRef(lazy = true) Map lazyMapOfReferences; + } + + @Data + @Document + public static class Related { + + final @Id Long id; + final String description; + } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTestsAppConfig.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTestsAppConfig.java index 4088ba5e2..594efdab3 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTestsAppConfig.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTestsAppConfig.java @@ -50,9 +50,4 @@ public class ApplicationContextEventTestsAppConfig extends AbstractMongoConfigur public SimpleMappingEventListener simpleMappingEventListener() { return new SimpleMappingEventListener(); } - - @Bean - public ParentMappingEventListener parentMappingEventListener() { - return new ParentMappingEventListener(); - } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/Parent.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/Parent.java deleted file mode 100644 index d4d2fcb98..000000000 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/Parent.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.springframework.data.mongodb.core.mapping.event; - -/** - * - * @author Jordi Llach - */ -public class Parent { - -} diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ParentMappingEventListener.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ParentMappingEventListener.java deleted file mode 100644 index 15f2e4b81..000000000 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ParentMappingEventListener.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.springframework.data.mongodb.core.mapping.event; - -import java.util.ArrayList; - -/** - * - * @author Jordi Llach - */ -public class ParentMappingEventListener extends AbstractMongoEventListener { - - public final ArrayList> onAfterLoadEvents = new ArrayList>(); - public final ArrayList> onAfterConvertEvents = new ArrayList>(); - - @Override - public void onAfterLoad(AfterLoadEvent event) { - onAfterLoadEvents.add(event); - } - - @Override - public void onAfterConvert(AfterConvertEvent event) { - onAfterConvertEvents.add(event); - } -} \ No newline at end of file diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/Related.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/Related.java deleted file mode 100644 index c4fcfb008..000000000 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/Related.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.springframework.data.mongodb.core.mapping.event; - -import java.io.Serializable; -import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; -import org.springframework.data.mongodb.core.mapping.Document; - -/** - * - * @author Jordi Llach - */ -@Document -public class Related -extends Parent -implements Serializable { - - private static final long serialVersionUID = -5719343113953216434L; - - @Id - private Long id; - private String description; - - - @PersistenceConstructor - public Related(Long id, String description) { - this.id = id; - this.description = description; - } - - public Long getId() { - return id; - } - - public String getDescription() { - return description; - } -} \ No newline at end of file diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/Root.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/Root.java deleted file mode 100644 index ad7811fd6..000000000 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/Root.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.springframework.data.mongodb.core.mapping.event; - -import java.io.Serializable; -import java.util.List; -import java.util.Map; -import org.springframework.data.annotation.Id; -import org.springframework.data.annotation.PersistenceConstructor; -import org.springframework.data.mongodb.core.mapping.DBRef; -import org.springframework.data.mongodb.core.mapping.Document; - -/** - * - * @author Jordi Llach - */ -@Document -public class Root -extends Parent -implements Serializable { - - private static final long serialVersionUID = -3211692873265644541L; - - @Id - private Long id; - - // simple - private Related embed; - - // dbref simple - @DBRef - private Related ref; - @DBRef(lazy = true) - private Related lazyRef; - - // collection support - @DBRef - private List listRef; - @DBRef(lazy = true) - private List listLazy; - - // map support - @DBRef - private Map mapRef; - @DBRef(lazy = true) - private Map mapLazy; - - @PersistenceConstructor - public Root(Long id, Related embed, Related ref, Related lazyRef, List listRef, List listLazy, - Map mapRef, Map mapLazy) { - this.id = id; - this.embed = embed; - this.ref = ref; - this.lazyRef = lazyRef; - this.listRef = listRef; - this.listLazy = listLazy; - this.mapRef = mapRef; - this.mapLazy = mapLazy; - } - - public Long getId() { - return id; - } - - public Related getEmbed() { - return embed; - } - - public Related getRef() { - return ref; - } - - public Related getLazyRef() { - return lazyRef; - } - - public List getListRef() { - return listRef; - } - - public List getListLazy() { - return listLazy; - } - - public Map getMapRef() { - return mapRef; - } - - public Map getMapLazy() { - return mapLazy; - } -} \ No newline at end of file