DATAMONGO-741 - Fixed check for nested property references in aggregation framework.
Fixed using the actual field reference instead of the field name on resolving. Added equals(…) and hashCode() methods to value objects. Added unit tests for TypeBasedAggregationOperationContext.
This commit is contained in:
@@ -242,6 +242,41 @@ public class ExposedFields implements Iterable<ExposedField> {
|
||||
public String toString() {
|
||||
return String.format("AggregationField: %s, synthetic: %s", field, synthetic);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof ExposedField)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ExposedField that = (ExposedField) obj;
|
||||
|
||||
return this.field.equals(that.field) && this.synthetic == that.synthetic;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
|
||||
result += 31 * field.hashCode();
|
||||
result += 31 * (synthetic ? 0 : 1);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -282,5 +317,34 @@ public class ExposedFields implements Iterable<ExposedField> {
|
||||
public String toString() {
|
||||
return String.format("$%s", getRaw());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof FieldReference)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FieldReference that = (FieldReference) obj;
|
||||
|
||||
return this.field.equals(that.field);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return field.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public abstract class ExposedFieldsAggregationOperationContext implements Aggreg
|
||||
*/
|
||||
@Override
|
||||
public FieldReference getReference(Field field) {
|
||||
return getReference(field.getName());
|
||||
return getReference(field.getTarget());
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -231,5 +232,40 @@ public class Fields implements Iterable<Field> {
|
||||
public String toString() {
|
||||
return String.format("AggregationField - name: %s, target: %s", name, target);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof AggregationField)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AggregationField that = (AggregationField) obj;
|
||||
|
||||
return this.name.equals(that.name) && ObjectUtils.nullSafeEquals(this.target, that.target);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
|
||||
result += 31 * name.hashCode();
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(target);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public class TypeBasedAggregationOperationContext implements AggregationOperatio
|
||||
@Override
|
||||
public FieldReference getReference(Field field) {
|
||||
|
||||
PropertyPath.from(field.getName(), type);
|
||||
PropertyPath.from(field.getTarget(), type);
|
||||
return getReferenceFor(field);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
package org.springframework.data.mongodb.core.aggregation;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link Aggregation}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class AggregationUnitTests {
|
||||
|
||||
@@ -59,17 +59,6 @@ public class GroupOperationUnitTests {
|
||||
assertThat(idClause.get("b"), is((Object) "$c"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateComplexIdForGroupOperationWithSingleComplexIdField() {
|
||||
|
||||
// Fields fields = fields().and("a", 42);
|
||||
// GroupOperation groupOperation = new GroupOperation(fields());
|
||||
//
|
||||
// assertThat(groupOperation.toDBObject(Aggregation.DEFAULT_CONTEXT), is(notNullValue()));
|
||||
// assertThat(groupOperation.id, is(notNullValue()));
|
||||
// assertThat(groupOperation.id, is((Object) new BasicDBObject("a", 42)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void groupFactoryMethodWithMultipleFieldsAndSumOperation() {
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.aggregation;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.mapping.PropertyReferenceException;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link TypeBasedAggregationOperationContext}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class TypeBasedAggregationOperationContextUnitTests {
|
||||
|
||||
MongoMappingContext context;
|
||||
MappingMongoConverter converter;
|
||||
QueryMapper mapper;
|
||||
|
||||
@Mock MongoDbFactory dbFactory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
this.context = new MongoMappingContext();
|
||||
this.converter = new MappingMongoConverter(dbFactory, context);
|
||||
this.mapper = new QueryMapper(converter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findsSimpleReference() {
|
||||
assertThat(getContext(Foo.class).getReference("bar"), is(notNullValue()));
|
||||
}
|
||||
|
||||
@Test(expected = PropertyReferenceException.class)
|
||||
public void rejectsInvalidFieldReference() {
|
||||
getContext(Foo.class).getReference("foo");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-741
|
||||
*/
|
||||
@Test
|
||||
public void returnsReferencesToNestedFieldsCorrectly() {
|
||||
|
||||
AggregationOperationContext context = getContext(Foo.class);
|
||||
|
||||
Field field = Fields.field("bar.name");
|
||||
|
||||
assertThat(context.getReference("bar.name"), is(notNullValue()));
|
||||
assertThat(context.getReference(field), is(notNullValue()));
|
||||
assertThat(context.getReference(field), is(context.getReference("bar.name")));
|
||||
}
|
||||
|
||||
private TypeBasedAggregationOperationContext getContext(Class<?> type) {
|
||||
return new TypeBasedAggregationOperationContext(type, context, mapper);
|
||||
}
|
||||
|
||||
static class Foo {
|
||||
|
||||
Bar bar;
|
||||
}
|
||||
|
||||
static class Bar {
|
||||
|
||||
String name;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user