Compare commits

...

9 Commits

Author SHA1 Message Date
Oliver Gierke
eef17dd000 DATAMONGO-1495 - Release version 1.9.4 (Hopper SR4). 2016-09-29 13:54:03 +02:00
Oliver Gierke
84dc03b9d1 DATAMONGO-1495 - Prepare 1.9.4 (Hopper SR4). 2016-09-29 13:53:26 +02:00
Oliver Gierke
0ce220d54f DATAMONGO-1495 - Updated changelog. 2016-09-29 13:53:19 +02:00
Oliver Gierke
b693136396 DATAMONGO-1499 - Updated changelog. 2016-09-29 11:42:09 +02:00
Oliver Gierke
3c117db43b 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.
2016-09-28 16:25:52 +02:00
Oliver Gierke
075ccb1d00 DATAMONGO-1497 - MappingMongoConverter now consistently uses DbObjectAccessor.
We now use DbObjectAccessor also for preliminary inspections of the source DBObject (e.g. whether a value is present at all). Previously we operated on the DBObject directly which caused issues with properties mapped to nested fields as the keys weren't exploded correctly and thus the check always failed.
2016-09-22 17:56:09 +02:00
Oliver Gierke
e3bddd1c19 DATAMONGO-1494 - Updated changelog. 2016-09-21 07:28:56 +02:00
Oliver Gierke
22b113ce64 DATAMONGO-1450 - After release cleanups. 2016-09-20 11:19:04 +02:00
Oliver Gierke
0f5e91b091 DATAMONGO-1450 - Prepare next development iteration. 2016-09-20 11:18:59 +02:00
12 changed files with 130 additions and 95 deletions

View File

@@ -5,7 +5,7 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.9.3.RELEASE</version>
<version>1.9.4.RELEASE</version>
<packaging>pom</packaging>
<name>Spring Data MongoDB</name>
@@ -15,7 +15,7 @@
<parent>
<groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId>
<version>1.8.3.RELEASE</version>
<version>1.8.4.RELEASE</version>
</parent>
<modules>
@@ -28,7 +28,7 @@
<properties>
<project.type>multi</project.type>
<dist.id>spring-data-mongodb</dist.id>
<springdata.commons>1.12.3.RELEASE</springdata.commons>
<springdata.commons>1.12.4.RELEASE</springdata.commons>
<mongo>2.14.3</mongo>
<mongo.osgi>2.13.0</mongo.osgi>
</properties>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.9.3.RELEASE</version>
<version>1.9.4.RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>
@@ -48,7 +48,7 @@
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.9.3.RELEASE</version>
<version>1.9.4.RELEASE</version>
</dependency>
<dependency>

View File

@@ -13,7 +13,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.9.3.RELEASE</version>
<version>1.9.4.RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.9.3.RELEASE</version>
<version>1.9.4.RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.9.3.RELEASE</version>
<version>1.9.4.RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2016 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.
@@ -15,24 +15,24 @@
*/
package org.springframework.data.mongodb.config;
import static org.springframework.beans.factory.config.BeanDefinition.*;
import static org.springframework.data.mongodb.config.BeanNames.*;
import java.lang.annotation.Annotation;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
import org.springframework.data.auditing.config.AuditingConfiguration;
import org.springframework.data.config.ParsingUtils;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.core.mapping.event.AuditingEventListener;
import org.springframework.data.support.IsNewStrategyFactory;
import org.springframework.util.Assert;
/**
@@ -71,7 +71,6 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
Assert.notNull(annotationMetadata, "AnnotationMetadata must not be null!");
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
defaultDependenciesIfNecessary(registry, annotationMetadata);
super.registerBeanDefinitions(annotationMetadata, registry);
}
@@ -85,7 +84,11 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
Assert.notNull(configuration, "AuditingConfiguration must not be null!");
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class);
builder.addConstructorArgReference(MAPPING_CONTEXT_BEAN_NAME);
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(MongoMappingContextLookup.class);
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
builder.addConstructorArgValue(definition.getBeanDefinition());
return configureDefaultAuditHandlerAttributes(configuration, builder);
}
@@ -102,29 +105,58 @@ class MongoAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport {
BeanDefinitionBuilder listenerBeanDefinitionBuilder = BeanDefinitionBuilder
.rootBeanDefinition(AuditingEventListener.class);
listenerBeanDefinitionBuilder.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(
getAuditingHandlerBeanName(), registry));
listenerBeanDefinitionBuilder
.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), registry));
registerInfrastructureBeanWithId(listenerBeanDefinitionBuilder.getBeanDefinition(),
AuditingEventListener.class.getName(), registry);
}
/**
* Register default bean definitions for a {@link MongoMappingContext} and an {@link IsNewStrategyFactory} in case we
* don't find beans with the assumed names in the registry.
*
* @param registry the {@link BeanDefinitionRegistry} to use to register the components into.
* @param source the source which the registered components shall be registered with
* Simple helper to be able to wire the {@link MappingContext} from a {@link MappingMongoConverter} bean available in
* the application context.
*
* @author Oliver Gierke
*/
private void defaultDependenciesIfNecessary(BeanDefinitionRegistry registry, Object source) {
static class MongoMappingContextLookup
implements FactoryBean<MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty>> {
if (!registry.containsBeanDefinition(MAPPING_CONTEXT_BEAN_NAME)) {
private final MappingMongoConverter converter;
RootBeanDefinition definition = new RootBeanDefinition(MongoMappingContext.class);
definition.setRole(ROLE_INFRASTRUCTURE);
definition.setSource(source);
/**
* Creates a new {@link MongoMappingContextLookup} for the given {@link MappingMongoConverter}.
*
* @param converter must not be {@literal null}.
*/
public MongoMappingContextLookup(MappingMongoConverter converter) {
this.converter = converter;
}
registry.registerBeanDefinition(MAPPING_CONTEXT_BEAN_NAME, definition);
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
@Override
public MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> getObject() throws Exception {
return converter.getMappingContext();
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
@Override
public Class<?> getObjectType() {
return MappingContext.class;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
@Override
public boolean isSingleton() {
return true;
}
}
}

View File

@@ -259,14 +259,14 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
// make sure id property is set before all other properties
Object idValue = null;
final DBObjectAccessor dbObjectAccessor = new DBObjectAccessor(dbo);
if (idProperty != null && new DBObjectAccessor(dbo).hasValue(idProperty)) {
if (idProperty != null && dbObjectAccessor.hasValue(idProperty)) {
idValue = getValueInternal(idProperty, dbo, evaluator, path);
accessor.setProperty(idProperty, idValue);
}
final ObjectPath currentPath = path.push(result, entity,
idValue != null ? dbo.get(idProperty.getFieldName()) : null);
final ObjectPath currentPath = path.push(result, entity, idValue != null ? dbObjectAccessor.get(idProperty) : null);
// Set properties not already set in the constructor
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
@@ -277,7 +277,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return;
}
if (!dbo.containsField(prop.getFieldName()) || entity.isConstructorArgument(prop)) {
if (entity.isConstructorArgument(prop) || !dbObjectAccessor.hasValue(prop)) {
return;
}
@@ -290,7 +290,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
public void doWithAssociation(Association<MongoPersistentProperty> association) {
final MongoPersistentProperty property = association.getInverse();
Object value = dbo.get(property.getFieldName());
Object value = dbObjectAccessor.get(property);
if (value == null || entity.isConstructorArgument(property)) {
return;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2016 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.
@@ -19,21 +19,15 @@ import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.Collections;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.data.config.ParsingUtils;
import org.springframework.data.mongodb.config.BeanNames;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean;
import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
import org.springframework.data.repository.config.RepositoryConfigurationSource;
import org.springframework.data.repository.config.XmlRepositoryConfigurationSource;
import org.w3c.dom.Element;
@@ -47,8 +41,6 @@ public class MongoRepositoryConfigurationExtension extends RepositoryConfigurati
private static final String MONGO_TEMPLATE_REF = "mongo-template-ref";
private static final String CREATE_QUERY_INDEXES = "create-query-indexes";
private boolean fallbackMappingContextCreated = false;
/*
* (non-Javadoc)
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModuleName()
@@ -81,7 +73,7 @@ public class MongoRepositoryConfigurationExtension extends RepositoryConfigurati
*/
@Override
protected Collection<Class<? extends Annotation>> getIdentifyingAnnotations() {
return Collections.<Class<? extends Annotation>> singleton(Document.class);
return Collections.<Class<? extends Annotation>>singleton(Document.class);
}
/*
@@ -90,19 +82,7 @@ public class MongoRepositoryConfigurationExtension extends RepositoryConfigurati
*/
@Override
protected Collection<Class<?>> getIdentifyingTypes() {
return Collections.<Class<?>> singleton(MongoRepository.class);
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#postProcess(org.springframework.beans.factory.support.BeanDefinitionBuilder, org.springframework.data.repository.config.RepositoryConfigurationSource)
*/
@Override
public void postProcess(BeanDefinitionBuilder builder, RepositoryConfigurationSource source) {
if (fallbackMappingContextCreated) {
builder.addPropertyReference("mappingContext", BeanNames.MAPPING_CONTEXT_BEAN_NAME);
}
return Collections.<Class<?>>singleton(MongoRepository.class);
}
/*
@@ -130,23 +110,4 @@ public class MongoRepositoryConfigurationExtension extends RepositoryConfigurati
builder.addPropertyReference("mongoOperations", attributes.getString("mongoTemplateRef"));
builder.addPropertyValue("createIndexesForQueryMethods", attributes.getBoolean("createIndexesForQueryMethods"));
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#registerBeansForRoot(org.springframework.beans.factory.support.BeanDefinitionRegistry, org.springframework.data.repository.config.RepositoryConfigurationSource)
*/
@Override
public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource configurationSource) {
super.registerBeansForRoot(registry, configurationSource);
if (!registry.containsBeanDefinition(BeanNames.MAPPING_CONTEXT_BEAN_NAME)) {
RootBeanDefinition definition = new RootBeanDefinition(MongoMappingContext.class);
definition.setRole(AbstractBeanDefinition.ROLE_INFRASTRUCTURE);
definition.setSource(configurationSource.getSource());
registry.registerBeanDefinition(BeanNames.MAPPING_CONTEXT_BEAN_NAME, definition);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2016 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.
@@ -19,8 +19,6 @@ import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import java.net.UnknownHostException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -30,8 +28,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.mongodb.core.AuditablePerson;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.stereotype.Repository;
@@ -123,22 +119,20 @@ public class AuditingViaJavaConfigRepositoriesTests {
@Configuration
@EnableMongoRepositories
@EnableMongoAuditing
static class SimpleConfigWithRepositories {
@Bean
public MongoTemplate mongoTemplate() throws UnknownHostException {
return new MongoTemplate(new SimpleMongoDbFactory(new MongoClient(), "database"));
}
}
static class SimpleConfigWithRepositories extends SimpleConfig {}
@Configuration
@EnableMongoAuditing
static class SimpleConfig {
static class SimpleConfig extends AbstractMongoConfiguration {
@Bean
public MongoTemplate mongoTemplate() throws UnknownHostException {
return new MongoTemplate(new SimpleMongoDbFactory(new MongoClient(), "database"));
@Override
public Mongo mongo() throws Exception {
return new MongoClient();
}
@Override
protected String getDatabaseName() {
return "database";
}
}
}

View File

@@ -2074,6 +2074,18 @@ public class MappingMongoConverterUnitTests {
assertThat(converter.read(ClassWithIntId.class, new BasicDBObject()), is(notNullValue()));
}
/**
* @see DATAMONGO-1497
*/
@Test
public void readsPropertyFromNestedFieldCorrectly() {
DBObject source = new BasicDBObject("nested", new BasicDBObject("sample", "value"));
TypeWithPropertyInNestedField result = converter.read(TypeWithPropertyInNestedField.class, source);
assertThat(result.sample, is("value"));
}
static class GenericType<T> {
T content;
}
@@ -2420,4 +2432,8 @@ public class MappingMongoConverterUnitTests {
throw new ConversionNotSupportedException(source, String.class, null);
}
}
static class TypeWithPropertyInNestedField {
@Field("nested.sample") String sample;
}
}

View File

@@ -1,6 +1,38 @@
Spring Data MongoDB Changelog
=============================
Changes in version 1.9.4.RELEASE (2016-09-29)
---------------------------------------------
* DATAMONGO-1498 - MongoMappingContext doesn't know about types usually auto-detected (JodaTime, JDK 8 date time types).
* DATAMONGO-1497 - MappingMongoConverter's check for whether a value is available for a property should use DbObjectAccessor.
* DATAMONGO-1495 - Release 1.9.4 (Hopper SR4).
Changes in version 1.8.6.RELEASE (2016-09-29)
---------------------------------------------
* DATAMONGO-1499 - Release 1.8.6 (Gosling SR6).
* DATAMONGO-1497 - MappingMongoConverter's check for whether a value is available for a property should use DbObjectAccessor.
Changes in version 1.8.5.RELEASE (2016-09-20)
---------------------------------------------
* DATAMONGO-1494 - Release 1.8.5 (Gosling SR5).
* DATAMONGO-1492 - Interface AggregationExpression in package org.springframework.data.mongodb.core.aggregation should be public.
* DATAMONGO-1485 - Querydsl MongodbSerializer does not take registered converters for Enums into account.
* DATAMONGO-1479 - MappingMongoConverter.convertToMongoType causes StackOverflowError for parameterized map value types.
* DATAMONGO-1471 - MappingMongoConverter attempts to set null value on potentially primitive identifier.
* DATAMONGO-1465 - String arguments passed to DefaultScriptOperations.execute() appear quoted in script.
* DATAMONGO-1453 - Parse error into GeoJsonPoint if coordinates are "integers".
* DATAMONGO-1449 - Replace legacy for loop with foreach in MappingMongoConverter.
* DATAMONGO-1445 - @Id annotated attribute of type BigInteger does not work with query methods.
* DATAMONGO-1437 - DefaultDbRefResolver swallows cause of non DataAccessException translatable Exception.
* DATAMONGO-1425 - NOT_CONTAINS keyword issues CONTAINS query.
* DATAMONGO-1423 - Nested document update doesn't apply converters on embedded maps.
* DATAMONGO-1412 - Document mapping rules for Java types to MongoDB representation.
* DATAMONGO-1406 - Query mapper does not use @Field field name when querying nested fields in combination with nested keywords.
* DATAMONGO-1401 - GeoJsonPoint error on update.
Changes in version 1.9.3.RELEASE (2016-09-20)
---------------------------------------------
* DATAMONGO-1493 - Typos in reference documentation.

View File

@@ -1,4 +1,4 @@
Spring Data MongoDB 1.9.3
Spring Data MongoDB 1.9.4
Copyright (c) [2010-2015] Pivotal Software, Inc.
This product is licensed to you under the Apache License, Version 2.0 (the "License").