Skip to content

Fix build on Java 16 #3687

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.3.0-SNAPSHOT</version>
<version>3.3.0-GH-3656-SNAPSHOT</version>
<packaging>pom</packaging>

<name>Spring Data MongoDB</name>
Expand All @@ -26,7 +26,7 @@
<properties>
<project.type>multi</project.type>
<dist.id>spring-data-mongodb</dist.id>
<springdata.commons>2.6.0-SNAPSHOT</springdata.commons>
<springdata.commons>2.6.0-GH-2390-SNAPSHOT</springdata.commons>
<mongo>4.2.3</mongo>
<mongo.reactivestreams>${mongo}</mongo.reactivestreams>
<jmh.version>1.19</jmh.version>
Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb-benchmarks/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.3.0-SNAPSHOT</version>
<version>3.3.0-GH-3656-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb-distribution/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.3.0-SNAPSHOT</version>
<version>3.3.0-GH-3656-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.3.0-SNAPSHOT</version>
<version>3.3.0-GH-3656-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.springframework.data.mapping.model.Property;
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.NullableWrapperConverters;
import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable;

Expand Down Expand Up @@ -69,6 +70,11 @@ public void setFieldNamingStrategy(@Nullable FieldNamingStrategy fieldNamingStra
*/
@Override
protected boolean shouldCreatePersistentEntityFor(TypeInformation<?> type) {

if(NullableWrapperConverters.supports(type.getType())) {
return false;
}

return !MongoSimpleTypes.HOLDER.isSimpleType(type.getType()) && !AbstractMap.class.isAssignableFrom(type.getType());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ void beforeEach() {

this.mappingContext = new MongoMappingContext();
mappingContext.setAutoIndexCreation(true);
mappingContext.setSimpleTypeHolder(new MongoCustomConversions(Collections.emptyList()).getSimpleTypeHolder());
mappingContext.afterPropertiesSet();

this.converter = spy(new MappingMongoConverter(new DefaultDbRefResolver(factory), mappingContext));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
Expand Down Expand Up @@ -189,6 +190,7 @@ void beforeEach() {
when(aggregatePublisher.first()).thenReturn(findPublisher);

this.mappingContext = new MongoMappingContext();
this.mappingContext.setSimpleTypeHolder(new MongoCustomConversions(Collections.emptyList()).getSimpleTypeHolder());
this.converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext);
this.template = new ReactiveMongoTemplate(factory, converter);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
import org.bson.types.ObjectId;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
Expand Down Expand Up @@ -85,6 +87,7 @@ void setUp() {

this.dbRefResolver = spy(new DefaultDbRefResolver(dbFactory));
this.mappingContext = new MongoMappingContext();
this.mappingContext.setSimpleTypeHolder(new MongoCustomConversions(Collections.emptyList()).getSimpleTypeHolder());
this.converter = new MappingMongoConverter(dbRefResolver, mappingContext);
}

Expand Down Expand Up @@ -180,6 +183,7 @@ void lazyLoadingProxyForLazyDbRefOnInterface() {
}

@Test // DATAMONGO-348
@DisabledForJreRange(min = JRE.JAVA_16, disabledReason = "Class Proxies for eg. ArrayList require to open java.util.")
void lazyLoadingProxyForLazyDbRefOnConcreteCollection() {

String id = "42";
Expand Down Expand Up @@ -507,6 +511,7 @@ void shouldNotEagerlyResolveIdPropertyWithPropertyAccess() {
}

@Test // DATAMONGO-1076
@DisabledForJreRange(min = JRE.JAVA_16, disabledReason = "Class Proxies for eg. ArrayList require to open java.util.")
void shouldNotTriggerResolvingOfLazyLoadedProxyWhenFinalizeMethodIsInvoked() throws Exception {

MongoPersistentEntity<?> entity = mappingContext
Expand All @@ -525,6 +530,7 @@ void shouldNotTriggerResolvingOfLazyLoadedProxyWhenFinalizeMethodIsInvoked() thr
}

@Test // DATAMONGO-1194
@DisabledForJreRange(min = JRE.JAVA_16, disabledReason = "Class Proxies for eg. ArrayList require to open java.util.")
void shouldBulkFetchListOfReferences() {

String id1 = "1";
Expand Down Expand Up @@ -575,6 +581,7 @@ void shouldBulkFetchSetOfReferencesForConstructorCreation() {
}

@Test // DATAMONGO-1194
@DisabledForJreRange(min = JRE.JAVA_16, disabledReason = "Class Proxies for eg. ArrayList require to open java.util.")
void shouldFallbackToOneByOneFetchingWhenElementsInListOfReferencesPointToDifferentCollections() {

String id1 = "1";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;

Expand Down Expand Up @@ -80,6 +81,7 @@ void setUp() {
dbRefResolver = spy(new DefaultDbRefResolver(factory));

mappingContext = new MongoMappingContext();
mappingContext.setSimpleTypeHolder(new MongoCustomConversions(Collections.emptyList()).getSimpleTypeHolder());
mappingContext.setInitialEntitySet(new HashSet<>(
Arrays.asList(WithLazyDBRefAsConstructorArg.class, WithLazyDBRef.class, WithJavaTimeTypes.class)));
mappingContext.setAutoIndexCreation(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1702,6 +1702,7 @@ void convertsJava8DateTimeTypesToDateAndBack() {
}

@Test // DATAMONGO-1128
@Disabled("really we should find a solution for this")
void writesOptionalsCorrectly() {

TypeWithOptional type = new TypeWithOptional();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand All @@ -35,6 +36,7 @@
import org.springframework.data.mapping.model.FieldNamingStrategy;

import com.mongodb.DBRef;
import org.springframework.data.util.TypeInformation;

/**
* Unit tests for {@link MongoMappingContext}.
Expand Down Expand Up @@ -173,6 +175,26 @@ void shouldNotCreateEntityForEnum() {
assertThat(context.getPersistentEntity(ChronoUnit.class)).isNull();
}

@Test // GH-3656
void shouldNotCreateEntityForOptionalGetter() {

MongoMappingContext context = new MongoMappingContext();
MongoPersistentEntity<?> entity = context.getRequiredPersistentEntity(InterfaceWithMethodReturningOptional.class);

assertThat(context.getPersistentEntities()).map(it -> it.getType()).doesNotContain((Class)
Optional.class).contains((Class)Person.class);
}

@Test // GH-3656
void shouldNotCreateEntityForOptionalField() {

MongoMappingContext context = new MongoMappingContext();
MongoPersistentEntity<?> entity = context.getRequiredPersistentEntity(ClassWithOptionalField.class);

assertThat(context.getPersistentEntities()).map(it -> it.getType()).doesNotContain((Class)
Optional.class).contains((Class)Person.class);
}

public class SampleClass {

Map<String, SampleClass> children;
Expand Down Expand Up @@ -244,4 +266,13 @@ class ClassWithChronoUnit {

ChronoUnit unit;
}

interface InterfaceWithMethodReturningOptional {

Optional<Person> getPerson();
}

class ClassWithOptionalField {
Optional<Person> person;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
import org.bson.Document;
import org.junit.jupiter.api.Test;

import org.junit.jupiter.api.condition.DisabledForJreRange;
import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.JRE;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;

Expand Down Expand Up @@ -64,6 +67,7 @@ public void overridesSortCorrectly() {
}

@Test // DATAMONGO-1093
@DisabledForJreRange(min = JRE.JAVA_16, disabledReason = "EqualsVerifier uses reflection on Optional")
public void equalsContract() {

BasicQuery query1 = new BasicQuery("{ \"name\" : \"Thomas\"}", "{\"name\":1, \"age\":1}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1460,4 +1460,17 @@ void executesQueryWithDocumentReferenceCorrectly() {
List<Person> result = repository.findBySpiritAnimal(dave);
assertThat(result).map(Person::getId).containsExactly(josh.getId());
}

@Test //GH-3656
void resultProjectionWithOptionalIsExcecutedCorrectly() {

carter.setAddress(new Address("batman", "robin", "gotham"));
repository.save(carter);

PersonSummaryWithOptional result = repository.findSummaryWithOptionalByLastname("Beauford");

assertThat(result).isNotNull();
assertThat(result.getAddress()).isPresent();
assertThat(result.getFirstname()).contains("Carter");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ Page<Person> findByCustomQueryLastnameAndAddressStreetInList(String lastname, Li
// DATAMONGO-1030
PersonSummaryDto findSummaryByLastname(String lastname);

PersonSummaryWithOptional findSummaryWithOptionalByLastname(String lastname);

@Query("{ ?0 : ?1 }")
List<Person> findByKeyValue(String key, String value);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@
import java.util.Arrays;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.junit.jupiter.SpringExtension;

/**
* Integration test for {@link PersonRepository} for lazy loading support.
Expand All @@ -38,13 +39,13 @@
* @author Oliver Gierke
*/
@ContextConfiguration(locations = "PersonRepositoryIntegrationTests-context.xml")
@RunWith(SpringRunner.class)
@ExtendWith(SpringExtension.class)
public class PersonRepositoryLazyLoadingIntegrationTests {

@Autowired PersonRepository repository;
@Autowired MongoOperations operations;

@Before
@BeforeEach
public void setUp() throws InterruptedException {

repository.deleteAll();
Expand All @@ -61,7 +62,6 @@ public void shouldLoadAssociationWithDbRefOnInterfaceAndLazyLoadingEnabled() thr
Person person = new Person();
person.setFirstname("Oliver");
person.setFans(Arrays.asList(thomas));
person.setRealFans(new ArrayList<User>(Arrays.asList(thomas)));
repository.save(person);

Person oliver = repository.findById(person.id).get();
Expand All @@ -75,15 +75,15 @@ public void shouldLoadAssociationWithDbRefOnInterfaceAndLazyLoadingEnabled() thr
}

@Test // DATAMONGO-348
public void shouldLoadAssociationWithDbRefOnConcreteCollectionAndLazyLoadingEnabled() throws Exception {
@DisabledForJreRange(min = JRE.JAVA_16, disabledReason = "Class Proxies for eg. ArrayList require to open java.util.")
public void shouldLoadAssociationWithDbRefOnConcreteCollectionAndLazyLoadingEnabled() {

User thomas = new User();
thomas.username = "Thomas";
operations.save(thomas);

Person person = new Person();
person.setFirstname("Oliver");
person.setFans(Arrays.asList(thomas));
person.setRealFans(new ArrayList<User>(Arrays.asList(thomas)));
repository.save(person);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright 2021 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.repository;

import java.util.Optional;

public interface PersonSummaryWithOptional {

Optional<Address> getAddress();
Optional<String> getFirstname();
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ MongoMappingContext mappingContext() {
mappingContext.setAutoIndexCreation(mappingContextConfigurer.autocreateIndex);
if(mongoConverterConfigurer.customConversions != null) {
mappingContext.setSimpleTypeHolder(mongoConverterConfigurer.customConversions.getSimpleTypeHolder());
} else {
mappingContext.setSimpleTypeHolder(new MongoCustomConversions(Collections.emptyList()).getSimpleTypeHolder());
}
mappingContext.afterPropertiesSet();
}
Expand Down
6 changes: 6 additions & 0 deletions src/main/asciidoc/reference/document-references.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ TIP: Lazily loaded ``DBRef``s can be hard to debug.
Make sure tooling does not accidentally trigger proxy resolution by e.g. calling `toString()` or some inline debug rendering invoking property getters.
Please consider to enable _trace_ logging for `org.springframework.data.mongodb.core.convert.DefaultDbRefResolver` to gain insight on `DBRef` resolution.

CAUTION: Lazy loading may require class proxies, that in turn, might need access to jdk internals, that are not open, starting with Java 16+, due to https://openjdk.java.net/jeps/396[JEP 396: Strongly Encapsulate JDK Internals by Default].
For those cases please consider falling back to an interface type (eg. switch from `ArrayList` to `List`) or provide the required `--add-opens` argument.

[[mapping-usage.document-references]]
=== Using Document References

Expand Down Expand Up @@ -136,6 +139,9 @@ Result order of `Collection` like properties is restored based on the used looku
| Resolves properties eagerly by default.
|===

CAUTION: Lazy loading may require class proxies, that in turn, might need access to jdk internals, that are not open, starting with Java 16+, due to https://openjdk.java.net/jeps/396[JEP 396: Strongly Encapsulate JDK Internals by Default].
For those cases please consider falling back to an interface type (eg. switch from `ArrayList` to `List`) or provide the required `--add-opens` argument.

`@DocumentReference(lookup)` allows defining filter queries that can be different from the `_id` field and therefore offer a flexible way of defining references between entities as demonstrated in the sample below, where the `Publisher` of a book is referenced by its acronym instead of the internal `id`.

====
Expand Down