Skip to content

Commit dcf88bc

Browse files
Copy over Embedded annotation from commons.
So we decided to move this to the store module for now. This gives us a little more time to rethink contextual properties in data-commons.
1 parent a84b248 commit dcf88bc

16 files changed

+191
-96
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@
4343
import org.springframework.core.CollectionFactory;
4444
import org.springframework.core.convert.ConversionService;
4545
import org.springframework.core.convert.support.DefaultConversionService;
46-
import org.springframework.data.annotation.Embedded;
47-
import org.springframework.data.annotation.Embedded.OnEmpty;
4846
import org.springframework.data.convert.TypeMapper;
4947
import org.springframework.data.mapping.Association;
5048
import org.springframework.data.mapping.MappingException;
@@ -64,6 +62,8 @@
6462
import org.springframework.data.mapping.model.SpELExpressionParameterValueProvider;
6563
import org.springframework.data.mongodb.CodecRegistryProvider;
6664
import org.springframework.data.mongodb.MongoDatabaseFactory;
65+
import org.springframework.data.mongodb.core.mapping.Embedded;
66+
import org.springframework.data.mongodb.core.mapping.Embedded.OnEmpty;
6767
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
6868
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
6969
import org.springframework.data.mongodb.core.mapping.event.AfterConvertCallback;
@@ -431,7 +431,8 @@ private void readProperties(MongoPersistentEntity<?> entity, PersistentPropertyA
431431

432432
if (prop.isEmbedded()) {
433433

434-
accessor.setProperty(prop, readEmbedded(documentAccessor, currentPath, prop, mappingContext.getPersistentEntity(prop)));
434+
accessor.setProperty(prop,
435+
readEmbedded(documentAccessor, currentPath, prop, mappingContext.getPersistentEntity(prop)));
435436
continue;
436437
}
437438

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* Copyright 2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.mongodb.core.mapping;
17+
18+
import java.lang.annotation.Documented;
19+
import java.lang.annotation.ElementType;
20+
import java.lang.annotation.Retention;
21+
import java.lang.annotation.RetentionPolicy;
22+
import java.lang.annotation.Target;
23+
24+
import javax.annotation.meta.When;
25+
26+
import org.springframework.core.annotation.AliasFor;
27+
28+
/**
29+
* The annotation to configure a value object as embedded (flattened out) in the target document.
30+
* <p />
31+
* Depending on the {@link OnEmpty value} of {@link #onEmpty()} the property is set to {@literal null} or an empty
32+
* instance in the case all embedded values are {@literal null} when reading from the result set.
33+
*
34+
* @author Christoph Strobl
35+
* @since 3.2
36+
*/
37+
@Documented
38+
@Retention(value = RetentionPolicy.RUNTIME)
39+
@Target(value = { ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD })
40+
public @interface Embedded {
41+
42+
/**
43+
* Set the load strategy for the embedded object if all contained fields yield {@literal null} values.
44+
* <p />
45+
* {@link Nullable @Embedded.Nullable} and {@link Empty @Embedded.Empty} offer shortcuts for this.
46+
*
47+
* @return never {@link} null.
48+
*/
49+
OnEmpty onEmpty();
50+
51+
/**
52+
* @return prefix for columns in the embedded value object. An empty {@link String} by default.
53+
*/
54+
String prefix() default "";
55+
56+
/**
57+
* Load strategy to be used {@link Embedded#onEmpty()}.
58+
*
59+
* @author Christoph Strobl
60+
*/
61+
enum OnEmpty {
62+
USE_NULL, USE_EMPTY
63+
}
64+
65+
/**
66+
* Shortcut for a nullable embedded property.
67+
*
68+
* <pre class="code">
69+
* &#64;Embedded.Nullable private Address address;
70+
* </pre>
71+
*
72+
* as alternative to the more verbose
73+
*
74+
* <pre class="code">
75+
* &#64;Embedded(onEmpty = USE_NULL) &#64;javax.annotation.Nonnull(when = When.MAYBE) private Address address;
76+
* </pre>
77+
*
78+
* @author Christoph Strobl
79+
* @see Embedded#onEmpty()
80+
*/
81+
@Embedded(onEmpty = OnEmpty.USE_NULL)
82+
@Documented
83+
@Retention(RetentionPolicy.RUNTIME)
84+
@Target({ ElementType.FIELD, ElementType.METHOD })
85+
@javax.annotation.Nonnull(when = When.MAYBE)
86+
@interface Nullable {
87+
88+
/**
89+
* @return prefix for columns in the embedded value object. An empty {@link String} by default.
90+
*/
91+
@AliasFor(annotation = Embedded.class, attribute = "prefix")
92+
String prefix() default "";
93+
94+
/**
95+
* @return value for columns in the embedded value object. An empty {@link String} by default.
96+
*/
97+
@AliasFor(annotation = Embedded.class, attribute = "prefix")
98+
String value() default "";
99+
}
100+
101+
/**
102+
* Shortcut for an empty embedded property.
103+
*
104+
* <pre class="code">
105+
* &#64;Embedded.Empty private Address address;
106+
* </pre>
107+
*
108+
* as alternative to the more verbose
109+
*
110+
* <pre class="code">
111+
* &#64;Embedded(onEmpty = USE_EMPTY) &#64;javax.annotation.Nonnull(when = When.NEVER) private Address address;
112+
* </pre>
113+
*
114+
* @author Christoph Strobl
115+
* @see Embedded#onEmpty()
116+
*/
117+
@Embedded(onEmpty = OnEmpty.USE_EMPTY)
118+
@Documented
119+
@Retention(RetentionPolicy.RUNTIME)
120+
@Target({ ElementType.FIELD, ElementType.METHOD })
121+
@javax.annotation.Nonnull(when = When.NEVER)
122+
@interface Empty {
123+
124+
/**
125+
* @return prefix for columns in the embedded value object. An empty {@link String} by default.
126+
*/
127+
@AliasFor(annotation = Embedded.class, attribute = "prefix")
128+
String prefix() default "";
129+
130+
/**
131+
* @return value for columns in the embedded value object. An empty {@link String} by default.
132+
*/
133+
@AliasFor(annotation = Embedded.class, attribute = "prefix")
134+
String value() default "";
135+
}
136+
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/EmbeddedEntityContext.java

+3-19
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,11 @@
11
/*
2-
* Copyright 2020. the original author or authors.
2+
* Copyright 2021 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.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
15-
*/
16-
17-
/*
18-
* Copyright 2020 the original author or authors.
19-
*
20-
* Licensed under the Apache License, Version 2.0 (the "License");
21-
* you may not use this file except in compliance with the License.
22-
* You may obtain a copy of the License at
23-
*
24-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* https://www.apache.org/licenses/LICENSE-2.0
259
*
2610
* Unless required by applicable law or agreed to in writing, software
2711
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -33,7 +17,7 @@
3317

3418
/**
3519
* @author Christoph Strobl
36-
* @since 2020/12
20+
* @since 3.2
3721
*/
3822
public class EmbeddedEntityContext {
3923

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/EmbeddedMongoPersistentEntity.java

+2-18
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,11 @@
11
/*
2-
* Copyright 2020. the original author or authors.
2+
* Copyright 2021 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.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
15-
*/
16-
17-
/*
18-
* Copyright 2020 the original author or authors.
19-
*
20-
* Licensed under the Apache License, Version 2.0 (the "License");
21-
* you may not use this file except in compliance with the License.
22-
* You may obtain a copy of the License at
23-
*
24-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* https://www.apache.org/licenses/LICENSE-2.0
259
*
2610
* Unless required by applicable law or agreed to in writing, software
2711
* distributed under the License is distributed on an "AS IS" BASIS,

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/EmbeddedMongoPersistentProperty.java

+2-19
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,11 @@
11
/*
2-
* Copyright 2020. the original author or authors.
2+
* Copyright 2021 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.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
15-
*/
16-
17-
/*
18-
* Copyright 2020 the original author or authors.
19-
*
20-
* Licensed under the Apache License, Version 2.0 (the "License");
21-
* you may not use this file except in compliance with the License.
22-
* You may obtain a copy of the License at
23-
*
24-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* https://www.apache.org/licenses/LICENSE-2.0
259
*
2610
* Unless required by applicable law or agreed to in writing, software
2711
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -35,7 +19,6 @@
3519
import java.lang.reflect.Field;
3620
import java.lang.reflect.Method;
3721

38-
import org.springframework.data.annotation.Embedded;
3922
import org.springframework.data.mapping.Association;
4023
import org.springframework.data.mapping.PersistentEntity;
4124
import org.springframework.data.mapping.PersistentPropertyAccessor;

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentProperty.java

+23-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@
1515
*/
1616
package org.springframework.data.mongodb.core.mapping;
1717

18+
import java.lang.annotation.ElementType;
19+
1820
import org.springframework.core.convert.converter.Converter;
19-
import org.springframework.data.annotation.Embedded;
2021
import org.springframework.data.annotation.Id;
2122
import org.springframework.data.mapping.PersistentEntity;
2223
import org.springframework.data.mapping.PersistentProperty;
24+
import org.springframework.data.mongodb.core.mapping.Embedded.OnEmpty;
25+
import org.springframework.data.util.NullableUtils;
2326
import org.springframework.lang.Nullable;
2427

2528
/**
@@ -124,6 +127,24 @@ default boolean hasExplicitWriteTarget() {
124127
return field != null ? !FieldType.IMPLICIT.equals(field.targetType()) : false;
125128
}
126129

130+
/**
131+
* @return {@literal true} if the property should be embedded.
132+
* @since 3.2
133+
*/
134+
default boolean isEmbedded() {
135+
return isEntity() && findAnnotation(Embedded.class) != null;
136+
}
137+
138+
/**
139+
* @return {@literal true} if the property generally allows {@literal null} values;
140+
* @since 3.2
141+
*/
142+
default boolean isNullable() {
143+
144+
return (isEmbedded() && findAnnotation(Embedded.class).onEmpty().equals(OnEmpty.USE_NULL))
145+
&& !NullableUtils.isNonNull(getField(), ElementType.FIELD);
146+
}
147+
127148
/**
128149
* Simple {@link Converter} implementation to transform a {@link MongoPersistentProperty} into its field name.
129150
*
@@ -138,7 +159,7 @@ enum PropertyToFieldNameConverter implements Converter<MongoPersistentProperty,
138159
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
139160
*/
140161
public String convert(MongoPersistentProperty source) {
141-
if(!source.isEmbedded()) {
162+
if (!source.isEmbedded()) {
142163
return source.getFieldName();
143164
}
144165
return "";

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/IndexEnsuringQueryCreationListener.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@
2323
import org.slf4j.Logger;
2424
import org.slf4j.LoggerFactory;
2525
import org.springframework.core.annotation.AnnotatedElementUtils;
26-
import org.springframework.data.annotation.Embedded;
2726
import org.springframework.data.domain.Sort;
2827
import org.springframework.data.domain.Sort.Direction;
2928
import org.springframework.data.domain.Sort.Order;
3029
import org.springframework.data.mongodb.UncategorizedMongoDbException;
3130
import org.springframework.data.mongodb.core.MongoOperations;
3231
import org.springframework.data.mongodb.core.index.Index;
3332
import org.springframework.data.mongodb.core.index.IndexOperationsProvider;
33+
import org.springframework.data.mongodb.core.mapping.Embedded;
3434
import org.springframework.data.mongodb.core.query.Collation;
3535
import org.springframework.data.mongodb.repository.query.MongoEntityMetadata;
3636
import org.springframework.data.mongodb.repository.query.PartTreeMongoQuery;
@@ -42,7 +42,6 @@
4242
import org.springframework.util.ReflectionUtils;
4343

4444
import com.mongodb.MongoException;
45-
import org.springframework.util.StringUtils;
4645

4746
/**
4847
* {@link QueryCreationListener} inspecting {@link PartTreeMongoQuery}s and creating an index for the properties it
@@ -91,7 +90,7 @@ public void onCreation(PartTreeMongoQuery query) {
9190
if (GEOSPATIAL_TYPES.contains(part.getType())) {
9291
return;
9392
}
94-
if(isIndexOnEmbeddedType(part)) {
93+
if (isIndexOnEmbeddedType(part)) {
9594
return;
9695
}
9796

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateEmbeddedTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
import org.junit.jupiter.api.Test;
2828
import org.junit.jupiter.api.extension.ExtendWith;
29-
import org.springframework.data.annotation.Embedded;
29+
import org.springframework.data.mongodb.core.mapping.Embedded;
3030
import org.springframework.data.mongodb.core.mapping.Field;
3131
import org.springframework.data.mongodb.core.query.Query;
3232
import org.springframework.data.mongodb.test.util.MongoTemplateExtension;

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUpdateUnitTests.java

-16
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import org.bson.Document;
2121
import org.junit.jupiter.api.Test;
22-
import org.springframework.data.annotation.Embedded;
2322

2423
/**
2524
* Unit tests for {@link AggregationUpdate}.
@@ -39,19 +38,4 @@ public void createPipelineWithMultipleStages() {
3938
.containsExactly(new Document("$set", new Document("stage-1", "value-1")),
4039
new Document("$unset", "stage-2"), new Document("$set", new Document("stage-3", "value-3")));
4140
}
42-
43-
@Test // DATAMONGO-2331
44-
public void xxx() {
45-
46-
47-
assertThat(AggregationUpdate.update() //
48-
.set("stage-1").toValue("value-1") //
49-
.unset("stage-2") //
50-
.set("stage-3").toValue("value-3") //
51-
.toPipeline(Aggregation.DEFAULT_CONTEXT)) //
52-
.containsExactly(new Document("$set", new Document("stage-1", "value-1")),
53-
new Document("$unset", "stage-2"), new Document("$set", new Document("stage-3", "value-3")));
54-
}
55-
56-
5741
}

0 commit comments

Comments
 (0)