Browse Source

DATAMONGO-1271 - Polishing.

Removed non Java 6 language features, reworked and added a few tests.

Original Pull Request: #322
pull/368/head
Christoph Strobl 10 years ago
parent
commit
7b8dadeb74
  1. 51
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java
  2. 446
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTests.java
  3. 5
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ApplicationContextEventTestsAppConfig.java
  4. 14
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/Parent.java
  5. 28
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ParentMappingEventListener.java
  6. 42
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/Related.java
  7. 95
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/Root.java

51
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.beans.BeansException;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.core.CollectionFactory; import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.ConversionException; import org.springframework.core.convert.ConversionException;
import org.springframework.core.convert.ConversionService; 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.MongoPersistentProperty;
import org.springframework.data.mongodb.core.mapping.event.AfterConvertEvent; 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.AfterLoadEvent;
import org.springframework.data.mongodb.core.mapping.event.MongoMappingEvent;
import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser;
@ -872,7 +872,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
@Override @Override
public Object getValueInternal(MongoPersistentProperty prop, DBObject dbo, SpELExpressionEvaluator evaluator, public Object getValueInternal(MongoPersistentProperty prop, DBObject dbo, SpELExpressionEvaluator evaluator,
ObjectPath path) { 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 DBObjectAccessor source;
private final SpELExpressionEvaluator evaluator; private final SpELExpressionEvaluator evaluator;
private final ObjectPath path; private final ObjectPath path;
private final boolean ignoreLazyDBRefProperties;
/** /**
* Creates a new {@link MongoDbPropertyValueProvider} for the given source, {@link SpELExpressionEvaluator} and * 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}. * @param path can be {@literal null}.
*/ */
public MongoDbPropertyValueProvider(DBObject source, SpELExpressionEvaluator evaluator, ObjectPath path) { 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(source);
Assert.notNull(evaluator); Assert.notNull(evaluator);
this.source = new DBObjectAccessor(source); this.source = new DBObjectAccessor(source);
this.evaluator = evaluator; this.evaluator = evaluator;
this.path = path; this.path = path;
this.ignoreLazyDBRefProperties = ignoreLazyDBRefProperties;
} }
/* /*
@ -1153,12 +1147,6 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
if (value == null) { if (value == null) {
return 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); return readValue(value, property.getTypeInformation(), path);
} }
@ -1220,24 +1208,39 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private <T> T potentiallyReadOrResolveDbRef(DBRef dbref, TypeInformation<?> type, ObjectPath path, Class<?> rawType) { private <T> T potentiallyReadOrResolveDbRef(DBRef dbref, TypeInformation<?> type, ObjectPath path, Class<?> rawType) {
if (rawType.equals(DBRef.class)) { if (rawType.equals(DBRef.class)) {
return (T) dbref; return (T) dbref;
} }
Object object = dbref == null ? null : path.getPathItem(dbref.getId(), dbref.getCollectionName()); Object object = dbref == null ? null : path.getPathItem(dbref.getId(), dbref.getCollectionName());
return (T) (object != null ? object : readAndConvertDBRef(dbref, type, path, rawType)); return (T) (object != null ? object : readAndConvertDBRef(dbref, type, path, rawType));
} }
private <T> T readAndConvertDBRef(DBRef dbref, TypeInformation<?> type, ObjectPath path, Class<?> rawType) { @SuppressWarnings("unchecked")
DBObject readRef = readRef(dbref); private <T> T readAndConvertDBRef(DBRef dbref, TypeInformation<?> type, ObjectPath path, final Class<?> rawType) {
final DBObject readRef = readRef(dbref);
final String collectionName = dbref.getCollectionName(); final String collectionName = dbref.getCollectionName();
if (canPublishEvent())
((ApplicationEventPublisher) this.applicationContext) if (readRef != null) {
.publishEvent(new AfterLoadEvent<T>(readRef, (Class<T>) rawType, collectionName)); maybeEmitEvent(new AfterLoadEvent<T>(readRef, (Class<T>) rawType, collectionName));
T t = (T) read(type, readRef, path); }
if (canPublishEvent())
((ApplicationEventPublisher) this.applicationContext) final T target = (T) read(type, readRef, path);
.publishEvent(new AfterConvertEvent<T>(readRef, t, collectionName));
return t; if (target != null) {
maybeEmitEvent(new AfterConvertEvent<T>(readRef, target, collectionName));
}
return target;
}
private void maybeEmitEvent(MongoMappingEvent<?> event) {
if (canPublishEvent()) {
this.applicationContext.publishEvent(event);
}
} }
private boolean canPublishEvent() { private boolean canPublishEvent() {

446
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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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; package org.springframework.data.mongodb.core.mapping.event;
import com.mongodb.DB; import static org.hamcrest.collection.IsCollectionWithSize.*;
import com.mongodb.DBObject; import static org.hamcrest.core.Is.*;
import com.mongodb.Mongo; import static org.hamcrest.core.IsEqual.*;
import com.mongodb.MongoClient; import static org.junit.Assert.*;
import com.mongodb.WriteConcern; import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.query.Query.*;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import static org.hamcrest.core.Is.is;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; 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.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation; 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 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. * Integration test for Mapping Events.
@ -48,14 +58,16 @@ import static org.springframework.data.mongodb.core.query.Query.query;
*/ */
public class ApplicationContextEventTests { public class ApplicationContextEventTests {
private static final String COLLECTION_NAME = "personPojoStringId"; private static final String COLLECTION_NAME = "personPojoStringId";
private static final String ROOT_COLLECTION_NAME = "root"; private static final String ROOT_COLLECTION_NAME = "root";
private static final String RELATED_COLLECTION_NAME = "related"; 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 ApplicationContext applicationContext;
private MongoTemplate template; private MongoTemplate template;
private SimpleMappingEventListener simpleMappingEventListener;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
@ -63,6 +75,7 @@ public class ApplicationContextEventTests {
applicationContext = new AnnotationConfigApplicationContext(ApplicationContextEventTestsAppConfig.class); applicationContext = new AnnotationConfigApplicationContext(ApplicationContextEventTestsAppConfig.class);
template = applicationContext.getBean(MongoTemplate.class); template = applicationContext.getBean(MongoTemplate.class);
template.setWriteConcern(WriteConcern.FSYNC_SAFE); template.setWriteConcern(WriteConcern.FSYNC_SAFE);
simpleMappingEventListener = applicationContext.getBean(SimpleMappingEventListener.class);
} }
@After @After
@ -82,10 +95,9 @@ public class ApplicationContextEventTests {
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void beforeSaveEvent() { public void beforeSaveEvent() {
PersonBeforeSaveListener personBeforeSaveListener = applicationContext.getBean(PersonBeforeSaveListener.class); PersonBeforeSaveListener personBeforeSaveListener = applicationContext.getBean(PersonBeforeSaveListener.class);
AfterSaveListener afterSaveListener = applicationContext.getBean(AfterSaveListener.class); AfterSaveListener afterSaveListener = applicationContext.getBean(AfterSaveListener.class);
SimpleMappingEventListener simpleMappingEventListener = applicationContext
.getBean(SimpleMappingEventListener.class);
assertEquals(0, personBeforeSaveListener.seenEvents.size()); assertEquals(0, personBeforeSaveListener.seenEvents.size());
assertEquals(0, afterSaveListener.seenEvents.size()); assertEquals(0, afterSaveListener.seenEvents.size());
@ -129,9 +141,6 @@ public class ApplicationContextEventTests {
@Test @Test
public void loadAndConvertEvents() { public void loadAndConvertEvents() {
SimpleMappingEventListener simpleMappingEventListener = applicationContext
.getBean(SimpleMappingEventListener.class);
PersonPojoStringId entity = new PersonPojoStringId("1", "Text"); PersonPojoStringId entity = new PersonPojoStringId("1", "Text");
template.insert(entity); template.insert(entity);
@ -153,9 +162,6 @@ public class ApplicationContextEventTests {
@Test @Test
public void loadEventsOnAggregation() { public void loadEventsOnAggregation() {
SimpleMappingEventListener simpleMappingEventListener = applicationContext
.getBean(SimpleMappingEventListener.class);
template.insert(new PersonPojoStringId("1", "Text")); template.insert(new PersonPojoStringId("1", "Text"));
template.aggregate(Aggregation.newAggregation(Aggregation.project("text")), PersonPojoStringId.class, template.aggregate(Aggregation.newAggregation(Aggregation.project("text")), PersonPojoStringId.class,
@ -177,9 +183,6 @@ public class ApplicationContextEventTests {
@Test @Test
public void deleteEvents() { public void deleteEvents() {
SimpleMappingEventListener simpleMappingEventListener = applicationContext
.getBean(SimpleMappingEventListener.class);
PersonPojoStringId entity = new PersonPojoStringId("1", "Text"); PersonPojoStringId entity = new PersonPojoStringId("1", "Text");
template.insert(entity); template.insert(entity);
@ -192,150 +195,231 @@ public class ApplicationContextEventTests {
assertThat(simpleMappingEventListener.onAfterDeleteEvents.get(0).getCollectionName(), is(COLLECTION_NAME)); assertThat(simpleMappingEventListener.onAfterDeleteEvents.get(0).getCollectionName(), is(COLLECTION_NAME));
} }
/** /**
* DATAMONGO-1271 DATAMONGO-1287 * @see DATAMONGO-1271
*/ */
@Test @Test
public void loadAndConvertEventsInInnerSimpleDBRef () throws Exception { public void publishesAfterLoadAndAfterConvertEventsForDBRef() throws Exception {
ParentMappingEventListener simpleMappingEventListener = applicationContext.getBean(ParentMappingEventListener.class);
Related embed = new Related(1L, "embed desc"); Related ref1 = new Related(2L, "related desc1");
Related ref1 = new Related(2L, "related desc1");
Related ref2 = new Related(3L, "related desc2"); template.insert(ref1);
template.insert(embed);
template.insert(ref1); Root source = new Root();
template.insert(ref2); source.id = 1L;
source.reference = ref1;
Root root = new Root(1L, embed, ref1, ref2, null, null, null, null);
template.insert(root); template.insert(source);
assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(0)); template.findOne(query(where("id").is(source.getId())), Root.class);
assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(0));
assertThat(simpleMappingEventListener.onAfterLoadEvents, hasSize(2));
// initially fetching ROOT document and also eagerly fetching 1 DBRef assertThat(simpleMappingEventListener.onAfterLoadEvents.get(0).getCollectionName(),
Root rootR = template.findOne(query(where("id").is(root.getId())), Root.class); is(equalTo(ROOT_COLLECTION_NAME)));
assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(2)); assertThat(simpleMappingEventListener.onAfterLoadEvents.get(1).getCollectionName(),
assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(2)); is(equalTo(RELATED_COLLECTION_NAME)));
// checking that no event is fired because those documents were previously eagerly fetched assertThat(simpleMappingEventListener.onAfterConvertEvents, hasSize(2));
rootR.getRef().getDescription(); assertThat(simpleMappingEventListener.onAfterConvertEvents.get(0).getCollectionName(),
rootR.getEmbed().getDescription(); is(equalTo(RELATED_COLLECTION_NAME)));
assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(2)); assertThat(simpleMappingEventListener.onAfterConvertEvents.get(1).getCollectionName(),
assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(2)); is(equalTo(ROOT_COLLECTION_NAME)));
// 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)); * @see DATAMONGO-1271
*/
// checking collectionNames fired @Test
assertThat(simpleMappingEventListener.onAfterLoadEvents.get(0).getCollectionName(), is(ROOT_COLLECTION_NAME)); public void publishesAfterLoadAndAfterConvertEventsForLazyLoadingDBRef() throws Exception {
assertThat(simpleMappingEventListener.onAfterConvertEvents.get(0).getCollectionName(), is(RELATED_COLLECTION_NAME));
assertThat(simpleMappingEventListener.onAfterLoadEvents.get(1).getCollectionName(), is(RELATED_COLLECTION_NAME)); Related ref1 = new Related(2L, "related desc1");
assertThat(simpleMappingEventListener.onAfterConvertEvents.get(1).getCollectionName(), is(ROOT_COLLECTION_NAME));
assertThat(simpleMappingEventListener.onAfterLoadEvents.get(2).getCollectionName(), is(RELATED_COLLECTION_NAME)); template.insert(ref1);
assertThat(simpleMappingEventListener.onAfterConvertEvents.get(2).getCollectionName(), is(RELATED_COLLECTION_NAME));
} Root source = new Root();
source.id = 1L;
/** source.lazyReference = ref1;
* DATAMONGO-1271 DATAMONGO-1287
*/ template.insert(source);
@Test
public void loadAndConvertEventsInInnerListDBRef() throws Exception { Root target = template.findOne(query(where("id").is(source.getId())), Root.class);
ParentMappingEventListener simpleMappingEventListener = applicationContext.getBean(ParentMappingEventListener.class);
Related embed = new Related(1L, "embed desc"); assertThat(simpleMappingEventListener.onAfterLoadEvents, hasSize(1));
Related ref1 = new Related(2L, "related desc1"); assertThat(simpleMappingEventListener.onAfterLoadEvents.get(0).getCollectionName(),
Related ref2 = new Related(3L, "related desc2"); is(equalTo(ROOT_COLLECTION_NAME)));
template.insert(embed);
template.insert(ref1); assertThat(simpleMappingEventListener.onAfterConvertEvents, hasSize(1));
template.insert(ref2); assertThat(simpleMappingEventListener.onAfterConvertEvents.get(0).getCollectionName(),
is(equalTo(ROOT_COLLECTION_NAME)));
Root root = new Root(1L, embed, null, null, Arrays.asList(ref1, ref2), Arrays.asList(ref1, ref2), null, null);
template.insert(root); target.getLazyReference().getDescription();
assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(0));
assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(0)); assertThat(simpleMappingEventListener.onAfterLoadEvents, hasSize(2));
assertThat(simpleMappingEventListener.onAfterLoadEvents.get(1).getCollectionName(),
// initially fetching ROOT document and also eagerly fetching 2 DBRef is(equalTo(RELATED_COLLECTION_NAME)));
Root rootR = template.findOne(query(where("id").is(root.getId())), Root.class);
assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(3)); assertThat(simpleMappingEventListener.onAfterConvertEvents, hasSize(2));
assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(3)); assertThat(simpleMappingEventListener.onAfterConvertEvents.get(1).getCollectionName(),
is(equalTo(RELATED_COLLECTION_NAME)));
// 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)); * @see DATAMONGO-1271
assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(3)); */
@Test
// fetching lazily dbref public void publishesAfterLoadAndAfterConvertEventsForListOfDBRef() throws Exception {
rootR.getListLazy().get(0).getDescription();
rootR.getListLazy().get(1).getDescription(); List<Related> references = Arrays.asList(new Related(20L, "ref 1"), new Related(30L, "ref 2"));
assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(5));
assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(5)); template.insert(references, Related.class);
// checking collectionNames fired Root source = new Root();
assertThat(simpleMappingEventListener.onAfterLoadEvents.get(0).getCollectionName(), is(ROOT_COLLECTION_NAME)); source.id = 1L;
assertThat(simpleMappingEventListener.onAfterConvertEvents.get(0).getCollectionName(), is(RELATED_COLLECTION_NAME)); source.listOfReferences = references;
assertThat(simpleMappingEventListener.onAfterLoadEvents.get(1).getCollectionName(), is(RELATED_COLLECTION_NAME));
assertThat(simpleMappingEventListener.onAfterConvertEvents.get(1).getCollectionName(), is(RELATED_COLLECTION_NAME)); template.insert(source);
assertThat(simpleMappingEventListener.onAfterLoadEvents.get(2).getCollectionName(), is(RELATED_COLLECTION_NAME));
assertThat(simpleMappingEventListener.onAfterConvertEvents.get(2).getCollectionName(), is(ROOT_COLLECTION_NAME)); template.findOne(query(where("id").is(source.getId())), Root.class);
assertThat(simpleMappingEventListener.onAfterLoadEvents.get(3).getCollectionName(), is(RELATED_COLLECTION_NAME));
assertThat(simpleMappingEventListener.onAfterConvertEvents.get(3).getCollectionName(), is(RELATED_COLLECTION_NAME)); assertThat(simpleMappingEventListener.onAfterLoadEvents, hasSize(3));
assertThat(simpleMappingEventListener.onAfterLoadEvents.get(4).getCollectionName(), is(RELATED_COLLECTION_NAME)); assertThat(simpleMappingEventListener.onAfterLoadEvents.get(0).getCollectionName(),
assertThat(simpleMappingEventListener.onAfterConvertEvents.get(4).getCollectionName(), is(RELATED_COLLECTION_NAME)); is(equalTo(ROOT_COLLECTION_NAME)));
} assertThat(simpleMappingEventListener.onAfterLoadEvents.get(1).getCollectionName(),
is(equalTo(RELATED_COLLECTION_NAME)));
/** assertThat(simpleMappingEventListener.onAfterLoadEvents.get(2).getCollectionName(),
* DATAMONGO-1271 DATAMONGO-1287 is(equalTo(RELATED_COLLECTION_NAME)));
*/
@Test assertThat(simpleMappingEventListener.onAfterConvertEvents, hasSize(3));
public void loadAndConvertEventsInInnerMapDBRef() throws Exception { assertThat(simpleMappingEventListener.onAfterConvertEvents.get(0).getCollectionName(),
ParentMappingEventListener simpleMappingEventListener = applicationContext.getBean(ParentMappingEventListener.class); is(equalTo(RELATED_COLLECTION_NAME)));
Related embed = new Related(1L, "embed desc"); assertThat(simpleMappingEventListener.onAfterConvertEvents.get(1).getCollectionName(),
Related ref1 = new Related(2L, "related desc1"); is(equalTo(RELATED_COLLECTION_NAME)));
Related ref2 = new Related(3L, "related desc2"); assertThat(simpleMappingEventListener.onAfterConvertEvents.get(2).getCollectionName(),
template.insert(embed); is(equalTo(ROOT_COLLECTION_NAME)));
template.insert(ref1); }
template.insert(ref2);
/**
Map<String,Related> mapRef = new HashMap(); * @see DATAMONGO-1271
mapRef.put("1", ref1); */
mapRef.put("2", ref2); @Test
Map<String,Related> mapLazy = new HashMap(); public void publishesAfterLoadAndAfterConvertEventsForLazyLoadingListOfDBRef() throws Exception {
mapLazy.put("1", ref1);
mapLazy.put("2", ref2); List<Related> references = Arrays.asList(new Related(20L, "ref 1"), new Related(30L, "ref 2"));
Root root = new Root(1L, embed, null, null, null, null, mapRef, mapLazy); template.insert(references, Related.class);
template.insert(root);
assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(0)); Root source = new Root();
assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(0)); source.id = 1L;
source.lazyListOfReferences = references;
// initially fetching ROOT document and also eagerly fetching 2 DBRef (eager map)
Root rootR = template.findOne(query(where("id").is(root.getId())), Root.class); template.insert(source);
assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(3));
assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(3)); Root target = template.findOne(query(where("id").is(source.getId())), Root.class);
// checking that accessing eagerly fetched map does not fire any new event assertThat(simpleMappingEventListener.onAfterLoadEvents, hasSize(1));
Assert.assertEquals(0, rootR.getMapRef().keySet().stream().filter(key -> rootR.getMapRef().get(key).getDescription() == null).count()); assertThat(simpleMappingEventListener.onAfterLoadEvents.get(0).getCollectionName(),
assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(3)); is(equalTo(ROOT_COLLECTION_NAME)));
assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(3)); assertThat(simpleMappingEventListener.onAfterConvertEvents, hasSize(1));
// accessing lazy map of dbref assertThat(simpleMappingEventListener.onAfterConvertEvents.get(0).getCollectionName(),
Assert.assertEquals(0, rootR.getMapLazy().keySet().stream().filter(key -> rootR.getMapLazy().get(key).getDescription() == null).count()); is(equalTo(ROOT_COLLECTION_NAME)));
assertThat(simpleMappingEventListener.onAfterLoadEvents.size(), is(5));
assertThat(simpleMappingEventListener.onAfterConvertEvents.size(), is(5)); target.getLazyListOfReferences().size();
// checking collectionNames fired assertThat(simpleMappingEventListener.onAfterLoadEvents, hasSize(3));
assertThat(simpleMappingEventListener.onAfterLoadEvents.get(0).getCollectionName(), is(ROOT_COLLECTION_NAME)); assertThat(simpleMappingEventListener.onAfterConvertEvents, hasSize(3));
assertThat(simpleMappingEventListener.onAfterConvertEvents.get(0).getCollectionName(), is(RELATED_COLLECTION_NAME));
assertThat(simpleMappingEventListener.onAfterLoadEvents.get(1).getCollectionName(), is(RELATED_COLLECTION_NAME)); assertThat(simpleMappingEventListener.onAfterLoadEvents.get(1).getCollectionName(),
assertThat(simpleMappingEventListener.onAfterConvertEvents.get(1).getCollectionName(), is(RELATED_COLLECTION_NAME)); is(equalTo(RELATED_COLLECTION_NAME)));
assertThat(simpleMappingEventListener.onAfterLoadEvents.get(2).getCollectionName(), is(RELATED_COLLECTION_NAME)); assertThat(simpleMappingEventListener.onAfterLoadEvents.get(2).getCollectionName(),
assertThat(simpleMappingEventListener.onAfterConvertEvents.get(2).getCollectionName(), is(ROOT_COLLECTION_NAME)); is(equalTo(RELATED_COLLECTION_NAME)));
assertThat(simpleMappingEventListener.onAfterLoadEvents.get(3).getCollectionName(), is(RELATED_COLLECTION_NAME)); assertThat(simpleMappingEventListener.onAfterConvertEvents.get(1).getCollectionName(),
assertThat(simpleMappingEventListener.onAfterConvertEvents.get(3).getCollectionName(), is(RELATED_COLLECTION_NAME)); is(equalTo(RELATED_COLLECTION_NAME)));
assertThat(simpleMappingEventListener.onAfterLoadEvents.get(4).getCollectionName(), is(RELATED_COLLECTION_NAME)); assertThat(simpleMappingEventListener.onAfterConvertEvents.get(2).getCollectionName(),
assertThat(simpleMappingEventListener.onAfterConvertEvents.get(4).getCollectionName(), is(RELATED_COLLECTION_NAME)); is(equalTo(RELATED_COLLECTION_NAME)));
} }
/**
* @see DATAMONGO-1271
*/
@Test
public void publishesAfterLoadAndAfterConvertEventsForMapOfDBRef() throws Exception {
Map<String, Related> references = new LinkedHashMap<String, Related>();
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<String, Related> references = new LinkedHashMap<String, Related>();
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) { private void comparePersonAndDbo(PersonPojoStringId p, PersonPojoStringId p2, DBObject dbo) {
assertEquals(p.getId(), p2.getId()); assertEquals(p.getId(), p2.getId());
assertEquals(p.getText(), p2.getText()); assertEquals(p.getText(), p2.getText());
@ -343,4 +427,28 @@ public class ApplicationContextEventTests {
assertEquals("1", dbo.get("_id")); assertEquals("1", dbo.get("_id"));
assertEquals("Text", dbo.get("text")); assertEquals("Text", dbo.get("text"));
} }
@Data
@Document
public static class Root {
@Id Long id;
@DBRef Related reference;
@DBRef(lazy = true) Related lazyReference;
@DBRef List<Related> listOfReferences;
@DBRef(lazy = true) List<Related> lazyListOfReferences;
@DBRef Map<String, Related> mapOfReferences;
@DBRef(lazy = true) Map<String, Related> lazyMapOfReferences;
}
@Data
@Document
public static class Related {
final @Id Long id;
final String description;
}
} }

5
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() { public SimpleMappingEventListener simpleMappingEventListener() {
return new SimpleMappingEventListener(); return new SimpleMappingEventListener();
} }
@Bean
public ParentMappingEventListener parentMappingEventListener() {
return new ParentMappingEventListener();
}
} }

14
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/Parent.java

@ -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 {
}

28
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/ParentMappingEventListener.java

@ -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<Parent> {
public final ArrayList<AfterLoadEvent<Parent>> onAfterLoadEvents = new ArrayList<AfterLoadEvent<Parent>>();
public final ArrayList<AfterConvertEvent<Parent>> onAfterConvertEvents = new ArrayList<AfterConvertEvent<Parent>>();
@Override
public void onAfterLoad(AfterLoadEvent<Parent> event) {
onAfterLoadEvents.add(event);
}
@Override
public void onAfterConvert(AfterConvertEvent<Parent> event) {
onAfterConvertEvents.add(event);
}
}

42
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/Related.java

@ -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;
}
}

95
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/Root.java

@ -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<Related> listRef;
@DBRef(lazy = true)
private List<Related> listLazy;
// map support
@DBRef
private Map<String, Related> mapRef;
@DBRef(lazy = true)
private Map<String, Related> mapLazy;
@PersistenceConstructor
public Root(Long id, Related embed, Related ref, Related lazyRef, List<Related> listRef, List<Related> listLazy,
Map<String, Related> mapRef, Map<String, Related> 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<Related> getListRef() {
return listRef;
}
public List<Related> getListLazy() {
return listLazy;
}
public Map<String, Related> getMapRef() {
return mapRef;
}
public Map<String, Related> getMapLazy() {
return mapLazy;
}
}
Loading…
Cancel
Save