Skip to content

Commit 8d36e42

Browse files
committed
DATAMONGO-1498 - Removed defaulting of MongoMappingContext for repositories and auditing.
Previously we created a default bean definition for MongoMappingContext if none was present in the application context. That lookup for an existing one unfortunately comes too early, especially with Spring Boot in place. This then caused the MappingContext not being aware of the custom conversions and simply types registered by Boot. We now removed the defaulting relying on a MappingMongoConverter being present in the Application context (which usually is the case for the usage with AbstractMongoConfiguration or the XML <mongo:mapping-converter /> alternative. We use that bean to lookup the MappingContext.
1 parent b66bfae commit 8d36e42

File tree

3 files changed

+68
-81
lines changed

3 files changed

+68
-81
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingRegistrar.java

Lines changed: 54 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2014 the original author or authors.
2+
* Copyright 2013-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,24 +15,24 @@
1515
*/
1616
package org.springframework.data.mongodb.config;
1717

18-
import static org.springframework.beans.factory.config.BeanDefinition.*;
19-
import static org.springframework.data.mongodb.config.BeanNames.*;
20-
2118
import java.lang.annotation.Annotation;
2219

20+
import org.springframework.beans.factory.FactoryBean;
2321
import org.springframework.beans.factory.config.BeanDefinition;
22+
import org.springframework.beans.factory.support.AbstractBeanDefinition;
2423
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
2524
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
26-
import org.springframework.beans.factory.support.RootBeanDefinition;
2725
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
2826
import org.springframework.core.type.AnnotationMetadata;
2927
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
3028
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
3129
import org.springframework.data.auditing.config.AuditingConfiguration;
3230
import org.springframework.data.config.ParsingUtils;
33-
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
31+
import org.springframework.data.mapping.context.MappingContext;
32+
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
33+
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
34+
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
3435
import org.springframework.data.mongodb.core.mapping.event.AuditingEventListener;
35-
import org.springframework.data.support.IsNewStrategyFactory;
3636
import org.springframework.util.Assert;
3737

3838
/**
@@ -71,7 +71,6 @@ public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanD
7171
Assert.notNull(annotationMetadata, "AnnotationMetadata must not be null!");
7272
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
7373

74-
defaultDependenciesIfNecessary(registry, annotationMetadata);
7574
super.registerBeanDefinitions(annotationMetadata, registry);
7675
}
7776

@@ -85,7 +84,11 @@ protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingCon
8584
Assert.notNull(configuration, "AuditingConfiguration must not be null!");
8685

8786
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class);
88-
builder.addConstructorArgReference(MAPPING_CONTEXT_BEAN_NAME);
87+
88+
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(MongoMappingContextLookup.class);
89+
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
90+
91+
builder.addConstructorArgValue(definition.getBeanDefinition());
8992
return configureDefaultAuditHandlerAttributes(configuration, builder);
9093
}
9194

@@ -102,29 +105,58 @@ protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandle
102105

103106
BeanDefinitionBuilder listenerBeanDefinitionBuilder = BeanDefinitionBuilder
104107
.rootBeanDefinition(AuditingEventListener.class);
105-
listenerBeanDefinitionBuilder.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(
106-
getAuditingHandlerBeanName(), registry));
108+
listenerBeanDefinitionBuilder
109+
.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), registry));
107110

108111
registerInfrastructureBeanWithId(listenerBeanDefinitionBuilder.getBeanDefinition(),
109112
AuditingEventListener.class.getName(), registry);
110113
}
111114

112115
/**
113-
* Register default bean definitions for a {@link MongoMappingContext} and an {@link IsNewStrategyFactory} in case we
114-
* don't find beans with the assumed names in the registry.
115-
*
116-
* @param registry the {@link BeanDefinitionRegistry} to use to register the components into.
117-
* @param source the source which the registered components shall be registered with
116+
* Simple helper to be able to wire the {@link MappingContext} from a {@link MappingMongoConverter} bean available in
117+
* the application context.
118+
*
119+
* @author Oliver Gierke
118120
*/
119-
private void defaultDependenciesIfNecessary(BeanDefinitionRegistry registry, Object source) {
121+
static class MongoMappingContextLookup
122+
implements FactoryBean<MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty>> {
123+
124+
private final MappingMongoConverter converter;
125+
126+
/**
127+
* Creates a new {@link MongoMappingContextLookup} for the given {@link MappingMongoConverter}.
128+
*
129+
* @param converter must not be {@literal null}.
130+
*/
131+
public MongoMappingContextLookup(MappingMongoConverter converter) {
132+
this.converter = converter;
133+
}
120134

121-
if (!registry.containsBeanDefinition(MAPPING_CONTEXT_BEAN_NAME)) {
135+
/*
136+
* (non-Javadoc)
137+
* @see org.springframework.beans.factory.FactoryBean#getObject()
138+
*/
139+
@Override
140+
public MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> getObject() throws Exception {
141+
return converter.getMappingContext();
142+
}
122143

123-
RootBeanDefinition definition = new RootBeanDefinition(MongoMappingContext.class);
124-
definition.setRole(ROLE_INFRASTRUCTURE);
125-
definition.setSource(source);
144+
/*
145+
* (non-Javadoc)
146+
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
147+
*/
148+
@Override
149+
public Class<?> getObjectType() {
150+
return MappingContext.class;
151+
}
126152

127-
registry.registerBeanDefinition(MAPPING_CONTEXT_BEAN_NAME, definition);
153+
/*
154+
* (non-Javadoc)
155+
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
156+
*/
157+
@Override
158+
public boolean isSingleton() {
159+
return true;
128160
}
129161
}
130162
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/config/MongoRepositoryConfigurationExtension.java

Lines changed: 3 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2014 the original author or authors.
2+
* Copyright 2012-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,21 +19,15 @@
1919
import java.util.Collection;
2020
import java.util.Collections;
2121

22-
import org.springframework.beans.factory.support.AbstractBeanDefinition;
2322
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
24-
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
25-
import org.springframework.beans.factory.support.RootBeanDefinition;
2623
import org.springframework.core.annotation.AnnotationAttributes;
2724
import org.springframework.data.config.ParsingUtils;
28-
import org.springframework.data.mongodb.config.BeanNames;
2925
import org.springframework.data.mongodb.core.mapping.Document;
30-
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
3126
import org.springframework.data.mongodb.repository.MongoRepository;
3227
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean;
3328
import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
3429
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
3530
import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
36-
import org.springframework.data.repository.config.RepositoryConfigurationSource;
3731
import org.springframework.data.repository.config.XmlRepositoryConfigurationSource;
3832
import org.w3c.dom.Element;
3933

@@ -47,8 +41,6 @@ public class MongoRepositoryConfigurationExtension extends RepositoryConfigurati
4741
private static final String MONGO_TEMPLATE_REF = "mongo-template-ref";
4842
private static final String CREATE_QUERY_INDEXES = "create-query-indexes";
4943

50-
private boolean fallbackMappingContextCreated = false;
51-
5244
/*
5345
* (non-Javadoc)
5446
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModuleName()
@@ -81,7 +73,7 @@ public String getRepositoryFactoryClassName() {
8173
*/
8274
@Override
8375
protected Collection<Class<? extends Annotation>> getIdentifyingAnnotations() {
84-
return Collections.<Class<? extends Annotation>> singleton(Document.class);
76+
return Collections.<Class<? extends Annotation>>singleton(Document.class);
8577
}
8678

8779
/*
@@ -90,19 +82,7 @@ protected Collection<Class<? extends Annotation>> getIdentifyingAnnotations() {
9082
*/
9183
@Override
9284
protected Collection<Class<?>> getIdentifyingTypes() {
93-
return Collections.<Class<?>> singleton(MongoRepository.class);
94-
}
95-
96-
/*
97-
* (non-Javadoc)
98-
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#postProcess(org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.data.repository.config.RepositoryConfigurationSource)
99-
*/
100-
@Override
101-
public void postProcess(BeanDefinitionBuilder builder, RepositoryConfigurationSource source) {
102-
103-
if (fallbackMappingContextCreated) {
104-
builder.addPropertyReference("mappingContext", BeanNames.MAPPING_CONTEXT_BEAN_NAME);
105-
}
85+
return Collections.<Class<?>>singleton(MongoRepository.class);
10686
}
10787

10888
/*
@@ -130,23 +110,4 @@ public void postProcess(BeanDefinitionBuilder builder, AnnotationRepositoryConfi
130110
builder.addPropertyReference("mongoOperations", attributes.getString("mongoTemplateRef"));
131111
builder.addPropertyValue("createIndexesForQueryMethods", attributes.getBoolean("createIndexesForQueryMethods"));
132112
}
133-
134-
/*
135-
* (non-Javadoc)
136-
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#registerBeansForRoot(org.springframework.beans.factory.support.BeanDefinitionRegistry, org.springframework.data.repository.config.RepositoryConfigurationSource)
137-
*/
138-
@Override
139-
public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource configurationSource) {
140-
141-
super.registerBeansForRoot(registry, configurationSource);
142-
143-
if (!registry.containsBeanDefinition(BeanNames.MAPPING_CONTEXT_BEAN_NAME)) {
144-
145-
RootBeanDefinition definition = new RootBeanDefinition(MongoMappingContext.class);
146-
definition.setRole(AbstractBeanDefinition.ROLE_INFRASTRUCTURE);
147-
definition.setSource(configurationSource.getSource());
148-
149-
registry.registerBeanDefinition(BeanNames.MAPPING_CONTEXT_BEAN_NAME, definition);
150-
}
151-
}
152113
}

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AuditingViaJavaConfigRepositoriesTests.java

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2014 the original author or authors.
2+
* Copyright 2013-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,8 +19,6 @@
1919
import static org.junit.Assert.*;
2020
import static org.mockito.Mockito.*;
2121

22-
import java.net.UnknownHostException;
23-
2422
import org.junit.Before;
2523
import org.junit.Test;
2624
import org.junit.runner.RunWith;
@@ -30,8 +28,6 @@
3028
import org.springframework.context.annotation.Configuration;
3129
import org.springframework.data.domain.AuditorAware;
3230
import org.springframework.data.mongodb.core.AuditablePerson;
33-
import org.springframework.data.mongodb.core.MongoTemplate;
34-
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
3531
import org.springframework.data.mongodb.repository.MongoRepository;
3632
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
3733
import org.springframework.stereotype.Repository;
@@ -123,22 +119,20 @@ static interface AuditablePersonRepository extends MongoRepository<AuditablePers
123119

124120
@Configuration
125121
@EnableMongoRepositories
126-
@EnableMongoAuditing
127-
static class SimpleConfigWithRepositories {
128-
129-
@Bean
130-
public MongoTemplate mongoTemplate() throws UnknownHostException {
131-
return new MongoTemplate(new SimpleMongoDbFactory(new MongoClient(), "database"));
132-
}
133-
}
122+
static class SimpleConfigWithRepositories extends SimpleConfig {}
134123

135124
@Configuration
136125
@EnableMongoAuditing
137-
static class SimpleConfig {
126+
static class SimpleConfig extends AbstractMongoConfiguration {
138127

139-
@Bean
140-
public MongoTemplate mongoTemplate() throws UnknownHostException {
141-
return new MongoTemplate(new SimpleMongoDbFactory(new MongoClient(), "database"));
128+
@Override
129+
public Mongo mongo() throws Exception {
130+
return new MongoClient();
131+
}
132+
133+
@Override
134+
protected String getDatabaseName() {
135+
return "database";
142136
}
143137
}
144138
}

0 commit comments

Comments
 (0)