DATAMONGO-1373 - Allow usage of @AliasFor with mapping and indexing annotations.
We now support @AliasFor to build composed annotations with: @Document, @Id, @Field, @Indexed, @CompoundIndex, @GeoSpatialIndexed, @TextIndexed, @Query, and @Meta. Added missing license header to @Field. Original pull request: #347. Related tickets: DATACMNS-825.
This commit is contained in:
committed by
Oliver Gierke
parent
0b634f8340
commit
b2ce1700d2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 the original author or authors.
|
||||
* Copyright 2010-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.
|
||||
@@ -27,8 +27,9 @@ import java.lang.annotation.Target;
|
||||
* @author Laurent Canet
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface GeoSpatialIndexed {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-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.
|
||||
@@ -26,10 +26,11 @@ import java.lang.annotation.Target;
|
||||
* all fields marked with {@link TextIndexed} are combined into one single index. <br />
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @since 1.6
|
||||
*/
|
||||
@Documented
|
||||
@Target({ ElementType.FIELD })
|
||||
@Target({ ElementType.FIELD, ElementType.ANNOTATION_TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TextIndexed {
|
||||
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright 2011-2015 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.mapping;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* Copyright 2014-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.
|
||||
@@ -25,10 +25,11 @@ import org.springframework.data.annotation.QueryAnnotation;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @since 1.6
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
||||
@Documented
|
||||
@QueryAnnotation
|
||||
public @interface Meta {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -30,9 +30,10 @@ import org.springframework.data.annotation.QueryAnnotation;
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
||||
@Documented
|
||||
@QueryAnnotation
|
||||
public @interface Query {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2015 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -20,6 +20,7 @@ import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.data.geo.GeoPage;
|
||||
import org.springframework.data.geo.GeoResult;
|
||||
@@ -43,6 +44,7 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class MongoQueryMethod extends QueryMethod {
|
||||
|
||||
@@ -191,7 +193,7 @@ public class MongoQueryMethod extends QueryMethod {
|
||||
* @return
|
||||
*/
|
||||
Query getQueryAnnotation() {
|
||||
return method.getAnnotation(Query.class);
|
||||
return AnnotatedElementUtils.findMergedAnnotation(method, Query.class);
|
||||
}
|
||||
|
||||
TypeInformation<?> getReturnType() {
|
||||
@@ -213,7 +215,7 @@ public class MongoQueryMethod extends QueryMethod {
|
||||
* @since 1.6
|
||||
*/
|
||||
Meta getMetaAnnotation() {
|
||||
return method.getAnnotation(Meta.class);
|
||||
return AnnotatedElementUtils.findMergedAnnotation(method, Meta.class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2015 the original author or authors.
|
||||
* Copyright 2014-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.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.mongodb.core.index;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.data.mongodb.test.util.IsBsonObject.isBsonObject;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -30,6 +31,7 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.mongodb.core.DBObjectTestUtils;
|
||||
@@ -54,6 +56,7 @@ import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses({ IndexResolutionTests.class, GeoSpatialIndexResolutionTests.class, CompoundIndexResolutionTests.class,
|
||||
@@ -195,6 +198,42 @@ public class MongoPersistentEntityIndexResolverUnitTests {
|
||||
assertThat(indexDefinitions.get(0).getIndexOptions(),
|
||||
equalTo(new BasicDBObjectBuilder().add("name", "_name").get()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1373
|
||||
*/
|
||||
@Test
|
||||
public void resolveIndexDefinitionInComposedAnnotatedFields() {
|
||||
|
||||
List<IndexDefinitionHolder> indexDefinitions = prepareMappingContextAndResolveIndexForType(
|
||||
IndexedDocumentWithComposedAnnotations.class);
|
||||
|
||||
assertThat(indexDefinitions, hasSize(2));
|
||||
|
||||
IndexDefinitionHolder indexDefinitionHolder = indexDefinitions.get(1);
|
||||
|
||||
assertThat(indexDefinitionHolder.getIndexKeys(), isBsonObject().containing("fieldWithMyIndexName", 1));
|
||||
assertThat(indexDefinitionHolder.getIndexOptions(),
|
||||
isBsonObject().containing("sparse", true).containing("unique", true).containing("name", "my_index_name"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1373
|
||||
*/
|
||||
@Test
|
||||
public void resolveIndexDefinitionInCustomComposedAnnotatedFields() {
|
||||
|
||||
List<IndexDefinitionHolder> indexDefinitions = prepareMappingContextAndResolveIndexForType(
|
||||
IndexedDocumentWithComposedAnnotations.class);
|
||||
|
||||
assertThat(indexDefinitions, hasSize(2));
|
||||
|
||||
IndexDefinitionHolder indexDefinitionHolder = indexDefinitions.get(0);
|
||||
|
||||
assertThat(indexDefinitionHolder.getIndexKeys(), isBsonObject().containing("fieldWithDifferentIndexName", 1));
|
||||
assertThat(indexDefinitionHolder.getIndexOptions(),
|
||||
isBsonObject().containing("sparse", true).containing("name", "different_name").notContaining("unique"));
|
||||
}
|
||||
|
||||
@Document(collection = "Zero")
|
||||
static class IndexOnLevelZero {
|
||||
@@ -247,6 +286,44 @@ public class MongoPersistentEntityIndexResolverUnitTests {
|
||||
static class NoIndex {
|
||||
@Id String id;
|
||||
}
|
||||
|
||||
@Document
|
||||
static class IndexedDocumentWithComposedAnnotations {
|
||||
|
||||
@Id String id;
|
||||
@CustomIndexedAnnotation String fieldWithDifferentIndexName;
|
||||
@ComposedIndexedAnnotation String fieldWithMyIndexName;
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD })
|
||||
@ComposedIndexedAnnotation(indexName = "different_name", beUnique = false)
|
||||
static @interface CustomIndexedAnnotation {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD, ElementType.ANNOTATION_TYPE })
|
||||
@Indexed
|
||||
static @interface ComposedIndexedAnnotation {
|
||||
|
||||
@AliasFor(annotation = Indexed.class, attribute = "unique")
|
||||
boolean beUnique() default true;
|
||||
|
||||
@AliasFor(annotation = Indexed.class, attribute = "sparse")
|
||||
boolean beSparse() default true;
|
||||
|
||||
@AliasFor(annotation = Indexed.class, attribute = "name")
|
||||
String indexName() default "my_index_name";
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
@org.springframework.data.mongodb.core.mapping.Field
|
||||
static @interface ComposedFieldAnnotation {
|
||||
|
||||
@AliasFor(annotation = org.springframework.data.mongodb.core.mapping.Field.class, attribute = "value")
|
||||
String name() default "_id";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -319,6 +396,24 @@ public class MongoPersistentEntityIndexResolverUnitTests {
|
||||
indexDefinition.getIndexOptions(),
|
||||
equalTo(new BasicDBObjectBuilder().add("name", "location").add("min", 1).add("max", 100).add("bits", 2).get()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1373
|
||||
*/
|
||||
@Test
|
||||
public void resolvesComposedAnnotationIndexDefinitionOptionsCorrectly() {
|
||||
|
||||
List<IndexDefinitionHolder> indexDefinitions = prepareMappingContextAndResolveIndexForType(GeoSpatialIndexedDocumentWithComposedAnnotation.class);
|
||||
|
||||
IndexDefinition indexDefinition = indexDefinitions.get(0).getIndexDefinition();
|
||||
|
||||
assertThat(
|
||||
indexDefinition.getIndexKeys(),
|
||||
isBsonObject().containing("location", "geoHaystack").containing("What light?", 1));
|
||||
assertThat(
|
||||
indexDefinition.getIndexOptions(),
|
||||
isBsonObject().containing("name", "my_geo_index_name").containing("bucketSize", 2.0));
|
||||
}
|
||||
|
||||
@Document(collection = "Zero")
|
||||
static class GeoSpatialIndexOnLevelZero {
|
||||
@@ -342,6 +437,31 @@ public class MongoPersistentEntityIndexResolverUnitTests {
|
||||
type = GeoSpatialIndexType.GEO_2D)//
|
||||
Point location;
|
||||
}
|
||||
|
||||
@Document(collection = "WithComposedAnnotation")
|
||||
static class GeoSpatialIndexedDocumentWithComposedAnnotation {
|
||||
|
||||
@ComposedGeoSpatialIndexed//
|
||||
Point location;
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD })
|
||||
@GeoSpatialIndexed
|
||||
@interface ComposedGeoSpatialIndexed {
|
||||
|
||||
@AliasFor(annotation = GeoSpatialIndexed.class, attribute = "name")
|
||||
String indexName() default "my_geo_index_name";
|
||||
|
||||
@AliasFor(annotation = GeoSpatialIndexed.class, attribute = "additionalField")
|
||||
String theAdditionalFieldINeedToDefine() default "What light?";
|
||||
|
||||
@AliasFor(annotation = GeoSpatialIndexed.class, attribute = "bucketSize")
|
||||
double size() default 2;
|
||||
|
||||
@AliasFor(annotation = GeoSpatialIndexed.class, attribute = "type")
|
||||
GeoSpatialIndexType indexType() default GeoSpatialIndexType.GEO_HAYSTACK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -445,6 +565,20 @@ public class MongoPersistentEntityIndexResolverUnitTests {
|
||||
assertThat(indexDefinitions, hasSize(1));
|
||||
assertIndexPathAndCollection(new String[] { "foo", "bar" }, "CompoundIndexOnLevelZero", indexDefinitions.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1373
|
||||
*/
|
||||
@Test
|
||||
public void singleCompoundIndexUsingComposedAnnotationsOnTypeResolvedCorrectly() {
|
||||
|
||||
List<IndexDefinitionHolder> indexDefinitions = prepareMappingContextAndResolveIndexForType(CompoundIndexDocumentWithComposedAnnotation.class);
|
||||
|
||||
assertThat(indexDefinitions, hasSize(1));
|
||||
assertThat(indexDefinitions.get(0).getIndexKeys(), isBsonObject().containing("foo", 1).containing("bar", -1));
|
||||
assertThat(indexDefinitions.get(0).getIndexOptions(), isBsonObject().containing("name", "my_compound_index_name").
|
||||
containing("unique", true).containing("background", true));
|
||||
}
|
||||
|
||||
@Document(collection = "CompoundIndexOnLevelOne")
|
||||
static class CompoundIndexOnLevelOne {
|
||||
@@ -482,6 +616,34 @@ public class MongoPersistentEntityIndexResolverUnitTests {
|
||||
static class ComountIndexWithAutogeneratedName {
|
||||
|
||||
}
|
||||
|
||||
@Document(collection = "WithComposedAnnotation")
|
||||
@ComposedCompoundIndex
|
||||
static class CompoundIndexDocumentWithComposedAnnotation {
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE })
|
||||
@CompoundIndex
|
||||
@interface ComposedCompoundIndex {
|
||||
|
||||
@AliasFor(annotation = CompoundIndex.class, attribute = "def")
|
||||
String fields() default "{'foo': 1, 'bar': -1}";
|
||||
|
||||
@AliasFor(annotation = CompoundIndex.class, attribute = "background")
|
||||
boolean inBackground() default true;
|
||||
|
||||
@AliasFor(annotation = CompoundIndex.class, attribute = "name")
|
||||
String indexName() default "my_compound_index_name";
|
||||
|
||||
@AliasFor(annotation = CompoundIndex.class, attribute = "useGeneratedName")
|
||||
boolean useGeneratedName() default false;
|
||||
|
||||
@AliasFor(annotation = CompoundIndex.class, attribute = "unique")
|
||||
boolean isUnique() default true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -611,6 +773,18 @@ public class MongoPersistentEntityIndexResolverUnitTests {
|
||||
List<IndexDefinitionHolder> indexDefinitions = prepareMappingContextAndResolveIndexForType(DocumentWithOverlappingLanguageProps.class);
|
||||
assertThat(indexDefinitions.get(0).getIndexOptions().get("language_override"), is((Object) "lang"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1373
|
||||
*/
|
||||
@Test
|
||||
public void shouldResolveComposedAnnotationCorrectly() {
|
||||
|
||||
List<IndexDefinitionHolder> indexDefinitions = prepareMappingContextAndResolveIndexForType(TextIndexedDocumentWithComposedAnnotation.class);
|
||||
|
||||
DBObject weights = DBObjectTestUtils.getAsDBObject(indexDefinitions.get(0).getIndexOptions(), "weights");
|
||||
assertThat(weights, isBsonObject().containing("foo", 99f));
|
||||
}
|
||||
|
||||
@Document
|
||||
static class TextIndexOnSinglePropertyInRoot {
|
||||
@@ -696,6 +870,22 @@ public class MongoPersistentEntityIndexResolverUnitTests {
|
||||
String language;
|
||||
@Language String lang;
|
||||
}
|
||||
|
||||
@Document
|
||||
static class TextIndexedDocumentWithComposedAnnotation {
|
||||
|
||||
@ComposedTextIndexedAnnotation String foo;
|
||||
String lang;
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD, ElementType.ANNOTATION_TYPE })
|
||||
@TextIndexed
|
||||
static @interface ComposedTextIndexedAnnotation {
|
||||
|
||||
@AliasFor(annotation = TextIndexed.class, attribute = "weight")
|
||||
float heavyweight() default 99f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 by the original author(s).
|
||||
* Copyright 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.
|
||||
@@ -18,6 +18,10 @@ package org.springframework.data.mongodb.core.mapping;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Locale;
|
||||
|
||||
@@ -25,6 +29,7 @@ import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.model.FieldNamingStrategy;
|
||||
@@ -39,6 +44,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class BasicMongoPersistentPropertyUnitTests {
|
||||
|
||||
@@ -184,6 +190,29 @@ public class BasicMongoPersistentPropertyUnitTests {
|
||||
"id");
|
||||
assertThat(property.isIdProperty(), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1373
|
||||
*/
|
||||
@Test
|
||||
public void shouldConsiderComposedAnnotationsForIdField() {
|
||||
|
||||
MongoPersistentProperty property = getPropertyFor(DocumentWithComposedAnnotations.class,
|
||||
"myId");
|
||||
assertThat(property.isIdProperty(), is(true));
|
||||
assertThat(property.getFieldName(), is("_id"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1373
|
||||
*/
|
||||
@Test
|
||||
public void shouldConsiderComposedAnnotationsForFields() {
|
||||
|
||||
MongoPersistentProperty property = getPropertyFor(DocumentWithComposedAnnotations.class,
|
||||
"myField");
|
||||
assertThat(property.getFieldName(), is("myField"));
|
||||
}
|
||||
|
||||
private MongoPersistentProperty getPropertyFor(Field field) {
|
||||
return getPropertyFor(entity, field);
|
||||
@@ -253,4 +282,25 @@ public class BasicMongoPersistentPropertyUnitTests {
|
||||
|
||||
@Id @org.springframework.data.mongodb.core.mapping.Field("id") String id;
|
||||
}
|
||||
|
||||
static class DocumentWithComposedAnnotations {
|
||||
|
||||
@ComposedIdAnnotation @ComposedFieldAnnotation String myId;
|
||||
@ComposedFieldAnnotation(name = "myField") String myField;
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
@org.springframework.data.mongodb.core.mapping.Field
|
||||
static @interface ComposedFieldAnnotation {
|
||||
|
||||
@AliasFor(annotation = org.springframework.data.mongodb.core.mapping.Field.class, attribute = "value")
|
||||
String name() default "_id";
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
@Id
|
||||
static @interface ComposedIdAnnotation { }
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.mongodb.repository;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -129,4 +130,27 @@ public class ComplexIdRepositoryIntegrationTests {
|
||||
assertThat(loaded, is(Matchers.<UserWithComplexId> iterableWithSize(1)));
|
||||
assertThat(loaded, contains(userWithId));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1373
|
||||
*/
|
||||
@Test
|
||||
public void composedAnnotationFindQueryShouldWorkWhenUsingComplexId() {
|
||||
|
||||
repo.save(userWithId);
|
||||
|
||||
assertThat(repo.getUserUsingComposedAnnotationByComplexId(id), is(userWithId));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1373
|
||||
*/
|
||||
@Test
|
||||
public void composedAnnotationFindMetaShouldWorkWhenUsingComplexId() {
|
||||
|
||||
repo.save(userWithId);
|
||||
|
||||
assertThat(repo.findUsersUsingComposedMetaAnnotationByUserIds(Arrays.asList(id)), hasSize(0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,9 +15,15 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
@@ -30,4 +36,31 @@ public interface UserWithComplexIdRepository extends CrudRepository<UserWithComp
|
||||
|
||||
@Query("{'_id': ?0}")
|
||||
UserWithComplexId getUserByComplexId(MyId id);
|
||||
|
||||
@ComposedQueryAnnotation
|
||||
UserWithComplexId getUserUsingComposedAnnotationByComplexId(MyId id);
|
||||
|
||||
@ComposedMetaAnnotation
|
||||
@Query("{'_id': {$in: ?0}}")
|
||||
List<UserWithComplexId> findUsersUsingComposedMetaAnnotationByUserIds(Collection<MyId> ids);
|
||||
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.METHOD })
|
||||
@Document
|
||||
@Query
|
||||
@interface ComposedQueryAnnotation {
|
||||
|
||||
@AliasFor(annotation = Query.class, attribute = "value")
|
||||
String myQuery() default "{'_id': ?0}";
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.METHOD })
|
||||
@Meta
|
||||
@interface ComposedMetaAnnotation {
|
||||
|
||||
@AliasFor(annotation = Meta.class, attribute = "maxScanDocuments")
|
||||
long scanDocuments() default 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
[[new-features]]
|
||||
= New & Noteworthy
|
||||
|
||||
[[new-features.1-9-0]]
|
||||
== What's new in Spring Data MongoDB 1.9
|
||||
* The following annotations have been enabled to build own, composed annotations: `@Document`, `@Id`, `@Field`, `@Indexed`, `@CompoundIndex`, `@GeoSpatialIndexed`, `@TextIndexed`, `@Query`, `@Meta`.
|
||||
|
||||
|
||||
[[new-features.1-8-0]]
|
||||
== What's new in Spring Data MongoDB 1.8
|
||||
|
||||
|
||||
Reference in New Issue
Block a user