Compare commits
23 Commits
labs/build
...
3.1.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
595fde7b04 | ||
|
|
01f4e73b48 | ||
|
|
2934c4886b | ||
|
|
080c798721 | ||
|
|
7cfb68e6be | ||
|
|
1e24abe8e5 | ||
|
|
a316d156dc | ||
|
|
6563b125eb | ||
|
|
c9251b1b29 | ||
|
|
373f07e176 | ||
|
|
f5e2bdc7ef | ||
|
|
30e63fffe2 | ||
|
|
83136b4e60 | ||
|
|
56697545a3 | ||
|
|
76eecc443e | ||
|
|
1f81806809 | ||
|
|
2d348be5b2 | ||
|
|
bbbe369093 | ||
|
|
5aa29fc7b8 | ||
|
|
05fc6546ff | ||
|
|
2c6e645a3d | ||
|
|
20f702512b | ||
|
|
ad77f23364 |
20
Jenkinsfile
vendored
20
Jenkinsfile
vendored
@@ -3,7 +3,7 @@ pipeline {
|
||||
|
||||
triggers {
|
||||
pollSCM 'H/10 * * * *'
|
||||
upstream(upstreamProjects: "spring-data-commons/master", threshold: hudson.model.Result.SUCCESS)
|
||||
upstream(upstreamProjects: "spring-data-commons/2.4.x", threshold: hudson.model.Result.SUCCESS)
|
||||
}
|
||||
|
||||
options {
|
||||
@@ -46,16 +46,16 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Publish JDK 14 + MongoDB 4.2') {
|
||||
stage('Publish JDK 15 + MongoDB 4.2') {
|
||||
when {
|
||||
changeset "ci/openjdk14-mongodb-4.2/**"
|
||||
changeset "ci/openjdk15-mongodb-4.2/**"
|
||||
}
|
||||
agent { label 'data' }
|
||||
options { timeout(time: 30, unit: 'MINUTES') }
|
||||
|
||||
steps {
|
||||
script {
|
||||
def image = docker.build("springci/spring-data-openjdk14-with-mongodb-4.2.0", "ci/openjdk14-mongodb-4.2/")
|
||||
def image = docker.build("springci/spring-data-openjdk15-with-mongodb-4.2.0", "ci/openjdk15-mongodb-4.2/")
|
||||
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
|
||||
image.push()
|
||||
}
|
||||
@@ -68,7 +68,7 @@ pipeline {
|
||||
stage("test: baseline (jdk8)") {
|
||||
when {
|
||||
anyOf {
|
||||
branch 'master'
|
||||
branch '3.1.x'
|
||||
not { triggeredBy 'UpstreamCause' }
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,7 @@ pipeline {
|
||||
stage("Test other configurations") {
|
||||
when {
|
||||
allOf {
|
||||
branch 'master'
|
||||
branch '3.1.x'
|
||||
not { triggeredBy 'UpstreamCause' }
|
||||
}
|
||||
}
|
||||
@@ -139,10 +139,10 @@ pipeline {
|
||||
}
|
||||
}
|
||||
|
||||
stage("test: baseline (jdk14)") {
|
||||
stage("test: baseline (jdk15)") {
|
||||
agent {
|
||||
docker {
|
||||
image 'springci/spring-data-openjdk14-with-mongodb-4.2.0:latest'
|
||||
image 'springci/spring-data-openjdk15-with-mongodb-4.2.0:latest'
|
||||
label 'data'
|
||||
args '-v $HOME:/tmp/jenkins-home'
|
||||
}
|
||||
@@ -164,7 +164,7 @@ pipeline {
|
||||
stage('Release to artifactory') {
|
||||
when {
|
||||
anyOf {
|
||||
branch 'master'
|
||||
branch '3.1.x'
|
||||
not { triggeredBy 'UpstreamCause' }
|
||||
}
|
||||
}
|
||||
@@ -196,7 +196,7 @@ pipeline {
|
||||
|
||||
stage('Publish documentation') {
|
||||
when {
|
||||
branch 'master'
|
||||
branch '3.1.x'
|
||||
}
|
||||
agent {
|
||||
docker {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM adoptopenjdk/openjdk14:latest
|
||||
FROM adoptopenjdk/openjdk15:latest
|
||||
|
||||
ENV TZ=Etc/UTC
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
12
pom.xml
12
pom.xml
@@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.1.0-STATIC-METADATA-SNAPSHOT</version>
|
||||
<version>3.1.1</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>2.4.0-SNAPSHOT</version>
|
||||
<version>2.4.1</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
@@ -26,8 +26,8 @@
|
||||
<properties>
|
||||
<project.type>multi</project.type>
|
||||
<dist.id>spring-data-mongodb</dist.id>
|
||||
<springdata.commons>2.4.0-BUILD-TIME-DOMAIN-TYPE-METADATA-SNAPSHOT</springdata.commons>
|
||||
<mongo>4.1.0</mongo>
|
||||
<springdata.commons>2.4.1</springdata.commons>
|
||||
<mongo>4.1.1</mongo>
|
||||
<mongo.reactivestreams>${mongo}</mongo.reactivestreams>
|
||||
<jmh.version>1.19</jmh.version>
|
||||
</properties>
|
||||
@@ -134,8 +134,8 @@
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-libs-snapshot</id>
|
||||
<url>https://repo.spring.io/libs-snapshot</url>
|
||||
<id>spring-libs-release</id>
|
||||
<url>https://repo.spring.io/libs-release</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sonatype-libs-snapshot</id>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.1.0-STATIC-METADATA-SNAPSHOT</version>
|
||||
<version>3.1.1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.1.0-STATIC-METADATA-SNAPSHOT</version>
|
||||
<version>3.1.1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.1.0-STATIC-METADATA-SNAPSHOT</version>
|
||||
<version>3.1.1</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ class AggregationUtil {
|
||||
}
|
||||
|
||||
if (!(aggregation instanceof TypedAggregation)) {
|
||||
return Aggregation.DEFAULT_CONTEXT;
|
||||
return new RelaxedTypeBasedAggregationOperationContext(Object.class, mappingContext, queryMapper);
|
||||
}
|
||||
|
||||
Class<?> inputType = ((TypedAggregation) aggregation).getInputType();
|
||||
@@ -98,7 +98,7 @@ class AggregationUtil {
|
||||
*/
|
||||
List<Document> createPipeline(Aggregation aggregation, AggregationOperationContext context) {
|
||||
|
||||
if (!ObjectUtils.nullSafeEquals(context, Aggregation.DEFAULT_CONTEXT)) {
|
||||
if (ObjectUtils.nullSafeEquals(context, Aggregation.DEFAULT_CONTEXT)) {
|
||||
return aggregation.toPipeline(context);
|
||||
}
|
||||
|
||||
|
||||
@@ -707,10 +707,9 @@ class QueryOperations {
|
||||
*/
|
||||
List<Document> getUpdatePipeline(@Nullable Class<?> domainType) {
|
||||
|
||||
AggregationOperationContext context = domainType != null
|
||||
? new RelaxedTypeBasedAggregationOperationContext(domainType, mappingContext, queryMapper)
|
||||
: Aggregation.DEFAULT_CONTEXT;
|
||||
Class<?> type = domainType != null ? domainType : Object.class;
|
||||
|
||||
AggregationOperationContext context = new RelaxedTypeBasedAggregationOperationContext(type, mappingContext, queryMapper);
|
||||
return aggregationUtil.createPipeline((AggregationUpdate) update, context);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core;
|
||||
|
||||
import static org.springframework.data.mongodb.core.query.SerializationUtils.*;
|
||||
|
||||
import org.springframework.data.mongodb.core.aggregation.RelaxedTypeBasedAggregationOperationContext;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.function.Tuple2;
|
||||
@@ -2112,7 +2113,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
AggregationOperationContext context = agg instanceof TypedAggregation
|
||||
? new TypeBasedAggregationOperationContext(((TypedAggregation<?>) agg).getInputType(),
|
||||
getConverter().getMappingContext(), queryMapper)
|
||||
: Aggregation.DEFAULT_CONTEXT;
|
||||
: new RelaxedTypeBasedAggregationOperationContext(Object.class, mappingContext, queryMapper);
|
||||
|
||||
return agg.toPipeline(new PrefixingDelegatingAggregationOperationContext(context, "fullDocument",
|
||||
Arrays.asList("operationType", "fullDocument", "documentKey", "updateDescription", "ns")));
|
||||
|
||||
@@ -264,7 +264,7 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
|
||||
return new Document(getOperator(), fieldObject);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#getOperator()
|
||||
*/
|
||||
@@ -1450,6 +1450,14 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
|
||||
return field.getTarget();
|
||||
}
|
||||
|
||||
if (field.getTarget().equals(Fields.UNDERSCORE_ID)) {
|
||||
try {
|
||||
return context.getReference(field).getReferenceValue();
|
||||
} catch (java.lang.IllegalArgumentException e) {
|
||||
return Fields.UNDERSCORE_ID_REF;
|
||||
}
|
||||
}
|
||||
|
||||
// check whether referenced field exists in the context
|
||||
return context.getReference(field).getReferenceValue();
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentPropertyPath;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.ExposedFields.DirectFieldReference;
|
||||
@@ -29,6 +30,7 @@ import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldRefe
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -46,6 +48,7 @@ public class TypeBasedAggregationOperationContext implements AggregationOperatio
|
||||
private final Class<?> type;
|
||||
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
private final QueryMapper mapper;
|
||||
private final Lazy<MongoPersistentEntity<?>> entity;
|
||||
|
||||
/**
|
||||
* Creates a new {@link TypeBasedAggregationOperationContext} for the given type, {@link MappingContext} and
|
||||
@@ -65,6 +68,7 @@ public class TypeBasedAggregationOperationContext implements AggregationOperatio
|
||||
this.type = type;
|
||||
this.mappingContext = mappingContext;
|
||||
this.mapper = mapper;
|
||||
this.entity = Lazy.of(() -> mappingContext.getPersistentEntity(type));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -151,10 +155,14 @@ public class TypeBasedAggregationOperationContext implements AggregationOperatio
|
||||
|
||||
protected FieldReference getReferenceFor(Field field) {
|
||||
|
||||
if(entity.getNullable() == null) {
|
||||
return new DirectFieldReference(new ExposedField(field, true));
|
||||
}
|
||||
|
||||
PersistentPropertyPath<MongoPersistentProperty> propertyPath = mappingContext
|
||||
.getPersistentPropertyPath(field.getTarget(), type);
|
||||
.getPersistentPropertyPath(field.getTarget(), type);
|
||||
Field mappedField = field(field.getName(),
|
||||
propertyPath.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE));
|
||||
propertyPath.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE));
|
||||
|
||||
return new DirectFieldReference(new ExposedField(mappedField, true));
|
||||
}
|
||||
|
||||
@@ -142,12 +142,8 @@ public class UnionWithOperation implements AggregationOperation {
|
||||
|
||||
private AggregationOperationContext computeContext(AggregationOperationContext source) {
|
||||
|
||||
if (domainType == null) {
|
||||
return Aggregation.DEFAULT_CONTEXT;
|
||||
}
|
||||
|
||||
if (source instanceof TypeBasedAggregationOperationContext) {
|
||||
return ((TypeBasedAggregationOperationContext) source).continueOnMissingFieldReference(domainType);
|
||||
return ((TypeBasedAggregationOperationContext) source).continueOnMissingFieldReference(domainType != null ? domainType : Object.class);
|
||||
}
|
||||
|
||||
if (source instanceof ExposedFieldsAggregationOperationContext) {
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*
|
||||
* https://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.buildtimetypeinfo;
|
||||
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 2020/10
|
||||
*/
|
||||
public class Address {
|
||||
|
||||
String city;
|
||||
String street;
|
||||
|
||||
public Address(String city, String street) {
|
||||
this.city = city;
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Address{" + "city='" + city + '\'' + ", street='" + street + '\'' + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
Address address = (Address) o;
|
||||
|
||||
if (!ObjectUtils.nullSafeEquals(city, address.city)) {
|
||||
return false;
|
||||
}
|
||||
return ObjectUtils.nullSafeEquals(street, address.street);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = ObjectUtils.nullSafeHashCode(city);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(street);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*
|
||||
* https://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.buildtimetypeinfo;
|
||||
|
||||
import org.springframework.data.mapping.model.DomainTypeConstructor;
|
||||
import org.springframework.data.mapping.model.DomainTypeInformation;
|
||||
import org.springframework.data.mapping.model.Field;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 2020/10
|
||||
*/
|
||||
public class AddressTypeInformation extends DomainTypeInformation<Address> {
|
||||
|
||||
private static final AddressTypeInformation INSTANCE = new AddressTypeInformation();
|
||||
|
||||
private AddressTypeInformation() {
|
||||
|
||||
super(Address.class);
|
||||
|
||||
// CONSTRUCTOR
|
||||
setConstructor(computePreferredConstructor());
|
||||
|
||||
// FIELDS
|
||||
addField(Field.<Address> string("city").getter(Address::getCity));
|
||||
addField(Field.<Address> string("street").getter(Address::getStreet));
|
||||
}
|
||||
|
||||
public static AddressTypeInformation instance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private DomainTypeConstructor<Address> computePreferredConstructor() {
|
||||
return DomainTypeConstructor.<Address> builder().args("city", "street")
|
||||
.newInstanceFunction(args -> new Address((String) args[0], (String) args[1]));
|
||||
}
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*
|
||||
* https://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.buildtimetypeinfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 2020/10
|
||||
*/
|
||||
public class Person {
|
||||
|
||||
private long id;
|
||||
private String firstname, lastname; // TODO: we need a persistence constructor to resolve this here.
|
||||
private int age;
|
||||
private Address address;
|
||||
private List<String> nicknames;
|
||||
|
||||
public Person(String firstname, String lastname) {
|
||||
this.firstname = firstname;
|
||||
this.lastname = lastname;
|
||||
}
|
||||
|
||||
private Person(long id, String firstname, String lastname, int age, Address address, List<String> nicknames) {
|
||||
this.id = id;
|
||||
this.firstname = firstname;
|
||||
this.lastname = lastname;
|
||||
this.age = age;
|
||||
this.address = address;
|
||||
this.nicknames = nicknames;
|
||||
}
|
||||
|
||||
public String getFirstname() {
|
||||
return firstname;
|
||||
}
|
||||
|
||||
public String getLastname() {
|
||||
return lastname;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Person withId(long id) {
|
||||
|
||||
return new Person(id, firstname, lastname, age, address, nicknames);
|
||||
|
||||
}
|
||||
|
||||
public Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(Address address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public List<String> getNicknames() {
|
||||
return nicknames;
|
||||
}
|
||||
|
||||
public void setNicknames(List<String> nicknames) {
|
||||
this.nicknames = nicknames;
|
||||
}
|
||||
|
||||
public void setFirstname(String firstname) {
|
||||
this.firstname = firstname;
|
||||
}
|
||||
|
||||
public void setLastname(String lastname) {
|
||||
this.lastname = lastname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Person{" + "id=" + id + ", firstname='" + firstname + '\'' + ", lastname='" + lastname + '\'' + ", age="
|
||||
+ age + ", address=" + address + ", nicknames=" + nicknames + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
Person person = (Person) o;
|
||||
|
||||
if (id != person.id)
|
||||
return false;
|
||||
if (age != person.age)
|
||||
return false;
|
||||
if (!ObjectUtils.nullSafeEquals(firstname, person.firstname)) {
|
||||
return false;
|
||||
}
|
||||
if (!ObjectUtils.nullSafeEquals(lastname, person.lastname)) {
|
||||
return false;
|
||||
}
|
||||
if (!ObjectUtils.nullSafeEquals(address, person.address)) {
|
||||
return false;
|
||||
}
|
||||
return ObjectUtils.nullSafeEquals(nicknames, person.nicknames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = (int) (id ^ (id >>> 32));
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(firstname);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(lastname);
|
||||
result = 31 * result + age;
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(address);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(nicknames);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*
|
||||
* https://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.buildtimetypeinfo;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.mapping.model.DomainTypeConstructor;
|
||||
import org.springframework.data.mapping.model.DomainTypeInformation;
|
||||
import org.springframework.data.mapping.model.Field;
|
||||
import org.springframework.data.mapping.model.ListTypeInformation;
|
||||
import org.springframework.data.mapping.model.StringTypeInformation;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.FieldType;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 2020/10
|
||||
*/
|
||||
public class PersonTypeInformation extends DomainTypeInformation<Person> {
|
||||
|
||||
private static final PersonTypeInformation INSTANCE = new PersonTypeInformation();
|
||||
|
||||
private PersonTypeInformation() {
|
||||
|
||||
super(Person.class);
|
||||
|
||||
// CONSTRUCTOR
|
||||
setConstructor(computePreferredConstructor());
|
||||
|
||||
// ANNOTATIONS
|
||||
addAnnotation(computeAtDocumentAnnotation());
|
||||
|
||||
// FIELDS
|
||||
addField(
|
||||
Field.<Person> int64("id").annotatedWithAtId().getter(Person::getId).wither((bean, id) -> bean.withId(id)));
|
||||
addField(Field.<Person> string("firstname").getter(Person::getFirstname).annotation(atFieldOnFirstname()));
|
||||
addField(Field.<Person> string("lastname").getter(Person::getLastname));
|
||||
addField(Field.<Person> int32("age").getter(Person::getAge).setter(Person::setAge));
|
||||
addField(Field.<Person, Address> type("address", AddressTypeInformation.instance()).getter(Person::getAddress)
|
||||
.setter(Person::setAddress));
|
||||
addField(Field.<Person, List<String>> type("nicknames", new ListTypeInformation<>(StringTypeInformation.instance()))
|
||||
.getter(Person::getNicknames).setter(Person::setNicknames));
|
||||
|
||||
}
|
||||
|
||||
public static PersonTypeInformation instance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private DomainTypeConstructor<Person> computePreferredConstructor() {
|
||||
return DomainTypeConstructor.<Person> builder().args("firstname", "lastname")
|
||||
.newInstanceFunction((args) -> new Person((String) args[0], (String) args[1]));
|
||||
}
|
||||
|
||||
private Document computeAtDocumentAnnotation() {
|
||||
return new Document() {
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return Document.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String value() {
|
||||
return collection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String collection() {
|
||||
return "star-wars";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String language() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String collation() {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Annotation atFieldOnFirstname() {
|
||||
|
||||
return new org.springframework.data.mongodb.core.mapping.Field() {
|
||||
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return org.springframework.data.mongodb.core.mapping.Field.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String value() {
|
||||
return "first-name";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return value();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int order() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldType targetType() {
|
||||
return FieldType.IMPLICIT;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1928,6 +1928,22 @@ public class AggregationTests {
|
||||
assertThat(results.getRawResults()).isEmpty();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2635
|
||||
void mapsEnumsInMatchClauseUsingInCriteriaCorrectly() {
|
||||
|
||||
WithEnum source = new WithEnum();
|
||||
source.enumValue = MyEnum.TWO;
|
||||
source.id = "id-1";
|
||||
|
||||
mongoTemplate.save(source);
|
||||
|
||||
Aggregation agg = newAggregation(match(where("enumValue").in(Collections.singletonList(MyEnum.TWO))));
|
||||
|
||||
AggregationResults<Document> results = mongoTemplate.aggregate(agg, mongoTemplate.getCollectionName(WithEnum.class),
|
||||
Document.class);
|
||||
assertThat(results.getMappedResults()).hasSize(1);
|
||||
}
|
||||
|
||||
private void createUsersWithReferencedPersons() {
|
||||
|
||||
mongoTemplate.dropCollection(User.class);
|
||||
@@ -2240,4 +2256,15 @@ public class AggregationTests {
|
||||
String p1;
|
||||
String p2;
|
||||
}
|
||||
|
||||
static enum MyEnum {
|
||||
ONE, TWO
|
||||
}
|
||||
|
||||
@lombok.Data
|
||||
static class WithEnum {
|
||||
|
||||
@Id String id;
|
||||
MyEnum enumValue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,11 @@ import org.bson.Document;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Cond;
|
||||
import org.springframework.data.mongodb.core.aggregation.ProjectionOperationUnitTests.BookWithFieldAnnotation;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
|
||||
/**
|
||||
@@ -582,6 +587,17 @@ public class AggregationUnitTests {
|
||||
"{\"attributeRecordArrays\": {\"$reduce\": {\"input\": \"$attributeRecordArrays\", \"initialValue\": [], \"in\": {\"$concatArrays\": [\"$$value\", \"$$this\"]}}}}"));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2644
|
||||
void projectOnIdIsAlwaysValid() {
|
||||
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
Document target = new Aggregation(bucket("start"), project("_id")).toDocument("collection-1",
|
||||
new RelaxedTypeBasedAggregationOperationContext(BookWithFieldAnnotation.class, mappingContext,
|
||||
new QueryMapper(new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext))));
|
||||
|
||||
assertThat(extractPipelineElement(target, 1, "$project")).isEqualTo(Document.parse(" { \"_id\" : \"$_id\" }"));
|
||||
}
|
||||
|
||||
private Document extractPipelineElement(Document agg, int index, String operation) {
|
||||
|
||||
List<Document> pipeline = (List<Document>) agg.get("pipeline");
|
||||
|
||||
@@ -23,7 +23,6 @@ import static org.springframework.data.mongodb.core.DocumentTestUtils.*;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URL;
|
||||
@@ -71,7 +70,6 @@ import org.springframework.data.mongodb.core.convert.DocumentAccessorUnitTests.N
|
||||
import org.springframework.data.mongodb.core.convert.DocumentAccessorUnitTests.ProjectingType;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverterUnitTests.ClassWithMapUsingEnumAsKey.FooBarEnum;
|
||||
import org.springframework.data.mongodb.core.geo.Sphere;
|
||||
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.FieldType;
|
||||
@@ -80,9 +78,7 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.mongodb.core.mapping.PersonPojoStringId;
|
||||
import org.springframework.data.mongodb.core.mapping.TextScore;
|
||||
import org.springframework.data.mongodb.core.mapping.event.AfterConvertCallback;
|
||||
import org.springframework.data.mongodb.buildtimetypeinfo.AddressTypeInformation;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.mongodb.buildtimetypeinfo.PersonTypeInformation;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
@@ -2183,108 +2179,6 @@ public class MappingMongoConverterUnitTests {
|
||||
assertThat(((LinkedHashMap) result.get("cluster")).get("_id")).isEqualTo(100L);
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void perf1() {
|
||||
//
|
||||
// ClassTypeInformation.warmCache(PersonTypeInformation.instance(), AddressTypeInformation.instance());
|
||||
//
|
||||
// MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
// mappingContext.setInitialEntitySet(new LinkedHashSet<>(
|
||||
// Arrays.asList(org.springframework.data.mongodb.xxx.Person.class, org.springframework.data.mongodb.xxx.Address.class)));
|
||||
// mappingContext.initialize();
|
||||
//
|
||||
// MappingMongoConverter converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext);
|
||||
//
|
||||
// org.springframework.data.mongodb.xxx.Person source = new org.springframework.data.mongodb.xxx.Person("spring", "data");
|
||||
// source.setAddress(new org.springframework.data.mongodb.xxx.Address("the city", "never sleeps"));
|
||||
// source.setAge(10);
|
||||
// source = source.withId(9876);
|
||||
// source.setNicknames(Arrays.asList("tick", "trick", "track"));
|
||||
//
|
||||
// StopWatch stopWatch = new StopWatch();
|
||||
//
|
||||
// List<org.bson.Document> sources = new ArrayList<>();
|
||||
// stopWatch.start("write");
|
||||
// for (int i = 0; i < 10000; i++) {
|
||||
//
|
||||
// org.bson.Document targetDocument = new org.bson.Document();
|
||||
// converter.write(source, targetDocument);
|
||||
//
|
||||
// sources.add(targetDocument);
|
||||
// }
|
||||
// stopWatch.stop();
|
||||
//
|
||||
// stopWatch.start("read");
|
||||
// for (org.bson.Document sourceDoc : sources) {
|
||||
// assertThat(converter.read(org.springframework.data.mongodb.xxx.Person.class, sourceDoc)).isEqualTo(source);
|
||||
// }
|
||||
// stopWatch.stop();
|
||||
//
|
||||
// System.out.println(stopWatch.prettyPrint());
|
||||
//
|
||||
// }
|
||||
|
||||
// public void perf2() {
|
||||
//
|
||||
// ClassTypeInformation.warmCache(new PersonTypeInformation(), new AddressTypeInformation());
|
||||
//
|
||||
// MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
// mappingContext.setInitialEntitySet(new LinkedHashSet<>(Arrays.asList(org.springframework.data.mongodb.xxx.Person.class,
|
||||
// org.springframework.data.mongodb.xxx.Address.class)));
|
||||
// mappingContext.initialize();
|
||||
//
|
||||
// MappingMongoConverter converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext);
|
||||
//
|
||||
// org.springframework.data.mongodb.xxx.Person source = new org.springframework.data.mongodb.xxx.Person("spring", "data");
|
||||
// source.setAddress(new org.springframework.data.mongodb.xxx.Address("the city", "never sleeps"));
|
||||
// source.setAge(10);
|
||||
// source.setId(9876);
|
||||
// source.setNicknames(Arrays.asList("tick", "trick", "track"));
|
||||
//
|
||||
// }
|
||||
|
||||
@Test
|
||||
public void staticEntityMetadata() {
|
||||
|
||||
ClassTypeInformation.warmCache(PersonTypeInformation.instance(), AddressTypeInformation.instance());
|
||||
|
||||
MongoMappingContext mappingContext = new MongoMappingContext();
|
||||
mappingContext.setInitialEntitySet(new LinkedHashSet<>(
|
||||
Arrays.asList(org.springframework.data.mongodb.buildtimetypeinfo.Person.class, org.springframework.data.mongodb.buildtimetypeinfo.Address.class)));
|
||||
mappingContext.initialize();
|
||||
|
||||
org.springframework.data.mongodb.buildtimetypeinfo.Person source = new org.springframework.data.mongodb.buildtimetypeinfo.Person("spring", "data");
|
||||
source.setAddress(new org.springframework.data.mongodb.buildtimetypeinfo.Address("the city", "never sleeps"));
|
||||
source.setAge(10);
|
||||
source = source.withId(9876);
|
||||
source.setNicknames(Arrays.asList("tick", "trick", "track"));
|
||||
|
||||
MappingMongoConverter converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext);
|
||||
org.bson.Document targetDocument = new org.bson.Document();
|
||||
System.out.println();
|
||||
System.out.println("------ WRITE -------");
|
||||
converter.write(source, targetDocument);
|
||||
System.out.println();
|
||||
|
||||
System.out.println("targetDocument: " + targetDocument);
|
||||
System.out.println();
|
||||
System.out.println("------ READ -------");
|
||||
assertThat(targetDocument).containsEntry("_id", 9876L);
|
||||
assertThat(targetDocument).containsEntry("first-name", "spring");
|
||||
assertThat(targetDocument).containsEntry("address",
|
||||
new org.bson.Document("city", "the city").append("street", "never sleeps"));
|
||||
assertThat(targetDocument).containsEntry("nicknames", Arrays.asList("tick", "trick", "track"));
|
||||
|
||||
org.springframework.data.mongodb.buildtimetypeinfo.Person targetEntity = converter.read(org.springframework.data.mongodb.buildtimetypeinfo.Person.class,
|
||||
targetDocument);
|
||||
System.out.println();
|
||||
System.out.println("targetEntity: " + targetEntity);
|
||||
assertThat(targetEntity).isEqualTo(source);
|
||||
|
||||
BasicMongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(org.springframework.data.mongodb.buildtimetypeinfo.Person.class);
|
||||
assertThat(entity.getCollection()).isEqualTo("star-wars");
|
||||
}
|
||||
|
||||
static class GenericType<T> {
|
||||
T content;
|
||||
}
|
||||
@@ -2755,34 +2649,4 @@ public class MappingMongoConverterUnitTests {
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
void xxx2() {
|
||||
|
||||
new Field() {
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String value() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int order() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldType targetType() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2020 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.staticmetadata;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.buildtimetypeinfo.Address;
|
||||
import org.springframework.data.mongodb.buildtimetypeinfo.AddressTypeInformation;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.mongodb.buildtimetypeinfo.Person;
|
||||
import org.springframework.data.mongodb.buildtimetypeinfo.PersonTypeInformation;
|
||||
|
||||
import com.mongodb.client.MongoClients;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 2020/10
|
||||
*/
|
||||
public class StaticMetadataTests {
|
||||
|
||||
MongoMappingContext mappingContext;
|
||||
MappingMongoConverter mongoConverter;
|
||||
MongoTemplate template;
|
||||
|
||||
Person luke;
|
||||
|
||||
@BeforeAll
|
||||
static void beforeAll() {
|
||||
ClassTypeInformation.warmCache(PersonTypeInformation.instance(), AddressTypeInformation.instance());
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
|
||||
mappingContext = new MongoMappingContext();
|
||||
mappingContext.setInitialEntitySet(new LinkedHashSet<>(
|
||||
Arrays.asList(Person.class, Address.class)));
|
||||
mappingContext.initialize();
|
||||
|
||||
mongoConverter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext);
|
||||
mongoConverter.afterPropertiesSet();
|
||||
|
||||
template = new MongoTemplate(new SimpleMongoClientDatabaseFactory(MongoClients.create(), "sem"), mongoConverter);
|
||||
|
||||
luke = new Person("luke", "skywalker");
|
||||
luke.setAddress(new Address("Mos Eisley", "WB154"));
|
||||
luke.setAge(22);
|
||||
luke = luke.withId(9876);
|
||||
luke.setNicknames(Arrays.asList("jedi", "wormie"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void readWrite() {
|
||||
|
||||
template.save(luke);
|
||||
|
||||
Document savedDocument = template.execute("star-wars",
|
||||
collection -> collection.find(new Document("_id", luke.getId())).first());
|
||||
System.out.println("savedDocument.toJson(): " + savedDocument.toJson());
|
||||
|
||||
Person savedEntity = template.findOne(query(where("id").is(luke.getId())), Person.class);
|
||||
System.out.println("savedEntity: " + savedEntity);
|
||||
|
||||
assertThat(savedEntity).isEqualTo(luke);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,10 +17,10 @@ public interface PersonRepository extends CrudReppsitory<Person, String> {
|
||||
@Aggregation("{ $group: { _id : $lastname, names : { $addToSet : $firstname } } }")
|
||||
List<PersonAggregate> groupByLastnameAndFirstnames(Sort sort); <2>
|
||||
|
||||
@Aggregation("{ $group: { _id : $lastname, names : { $addToSet : $?0 } } }")
|
||||
@Aggregation("{ $group: { _id : $lastname, names : { $addToSet : ?0 } } }")
|
||||
List<PersonAggregate> groupByLastnameAnd(String property); <3>
|
||||
|
||||
@Aggregation("{ $group: { _id : $lastname, names : { $addToSet : $?0 } } }")
|
||||
@Aggregation("{ $group: { _id : $lastname, names : { $addToSet : ?0 } } }")
|
||||
List<PersonAggregate> groupByLastnameAnd(String property, Pageable page); <4>
|
||||
|
||||
@Aggregation("{ $group : { _id : null, total : { $sum : $age } } }")
|
||||
|
||||
@@ -27,7 +27,7 @@ First, you need to set up a running MongoDB server. Refer to the https://docs.mo
|
||||
To create a Spring project in STS:
|
||||
|
||||
. Go to File -> New -> Spring Template Project -> Simple Spring Utility Project, and press Yes when prompted. Then enter a project and a package name, such as `org.spring.mongodb.example`.
|
||||
.Add the following to the pom.xml files `dependencies` element:
|
||||
. Add the following to the pom.xml files `dependencies` element:
|
||||
+
|
||||
[source,xml,subs="+attributes"]
|
||||
----
|
||||
|
||||
@@ -1,6 +1,51 @@
|
||||
Spring Data MongoDB Changelog
|
||||
=============================
|
||||
|
||||
Changes in version 3.1.1 (2020-11-11)
|
||||
-------------------------------------
|
||||
* DATAMONGO-2648 - Release 3.1.1 (2020.0.1).
|
||||
* DATAMONGO-2644 - Invalid reference '_id'! Error In spring data mongodb.
|
||||
* DATAMONGO-2635 - Enums Don't Properly Serialize In Aggregation Pipeline Facet.
|
||||
|
||||
|
||||
Changes in version 3.1.0 (2020-10-28)
|
||||
-------------------------------------
|
||||
* DATAMONGO-2642 - Upgrade to MongoDB Driver 4.1.1.
|
||||
* DATAMONGO-2639 - Release 3.1 GA (2020.0.0).
|
||||
* DATAMONGO-2638 - Fix documentation issues.
|
||||
|
||||
|
||||
Changes in version 3.0.5.RELEASE (2020-10-28)
|
||||
---------------------------------------------
|
||||
* DATAMONGO-2643 - Adopt to AssertJ API changes.
|
||||
* DATAMONGO-2638 - Fix documentation issues.
|
||||
* DATAMONGO-2633 - @Query annotation does not support $centerSphere.
|
||||
* DATAMONGO-2625 - Release 3.0.5 (Neumann SR5).
|
||||
|
||||
|
||||
Changes in version 2.2.11.RELEASE (2020-10-28)
|
||||
----------------------------------------------
|
||||
* DATAMONGO-2638 - Fix documentation issues.
|
||||
* DATAMONGO-2633 - @Query annotation does not support $centerSphere.
|
||||
* DATAMONGO-2624 - Release 2.2.11 (Moore SR11).
|
||||
|
||||
|
||||
Changes in version 2.1.21.RELEASE (2020-10-28)
|
||||
----------------------------------------------
|
||||
* DATAMONGO-2641 - Release 2.1.21 (Lovelace SR21).
|
||||
|
||||
|
||||
Changes in version 3.1.0-RC2 (2020-10-14)
|
||||
-----------------------------------------
|
||||
* DATAMONGO-2633 - @Query annotation does not support $centerSphere.
|
||||
* DATAMONGO-2630 - Add support for suspend repository query methods returning List<T>.
|
||||
* DATAMONGO-2626 - Release 3.1 RC2 (2020.0.0).
|
||||
* DATAMONGO-2623 - Add support for custom Aggregation expressions.
|
||||
* DATAMONGO-2622 - Add support for $unionWith aggregation.
|
||||
* DATAMONGO-2596 - Introduce extension to render KProperty/KPropertyPath as property path.
|
||||
* DATAMONGO-2294 - Support multiple parameters for query field projections.
|
||||
|
||||
|
||||
Changes in version 3.1.0-RC1 (2020-09-16)
|
||||
-----------------------------------------
|
||||
* DATAMONGO-2621 - Adapt to changed array assertions in AssertJ.
|
||||
@@ -3168,6 +3213,12 @@ Repository
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Spring Data MongoDB 3.1 RC1 (2020.0.0)
|
||||
Spring Data MongoDB 3.1.1 (2020.0.1)
|
||||
Copyright (c) [2010-2019] Pivotal Software, Inc.
|
||||
|
||||
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||
@@ -18,3 +18,6 @@ conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user