DATACMNS-867 - Further fixes.
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mapping.context;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@@ -498,12 +499,16 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
private final class PersistentPropertyCreator implements FieldCallback {
|
||||
|
||||
private final @NonNull E entity;
|
||||
private final @NonNull Map<String, PropertyDescriptor> descriptors;
|
||||
private final Map<String, PropertyDescriptor> remainingDescriptors = new HashMap<>();
|
||||
private final @NonNull Map<String, PropertyDescriptor> remainingDescriptors;
|
||||
|
||||
public PersistentPropertyCreator(E entity, Map<String, PropertyDescriptor> descriptors) {
|
||||
this(entity, descriptors, descriptors);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
|
||||
@@ -115,7 +115,7 @@ class CrudRepositoryInvoker extends ReflectionRepositoryInvoker {
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isRedeclaredMethod(Optional<Method> method) {
|
||||
private static boolean isRedeclaredMethod(Optional<Method> method) {
|
||||
return method.map(it -> !it.getDeclaringClass().equals(CrudRepository.class)).orElse(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.data.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
@@ -35,7 +36,6 @@ import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
class PagingAndSortingRepositoryInvoker extends CrudRepositoryInvoker {
|
||||
|
||||
private final PagingAndSortingRepository<Object, Serializable> repository;
|
||||
|
||||
private final boolean customFindAll;
|
||||
|
||||
/**
|
||||
@@ -63,7 +63,7 @@ class PagingAndSortingRepositoryInvoker extends CrudRepositoryInvoker {
|
||||
*/
|
||||
@Override
|
||||
public Iterable<Object> invokeFindAll(Sort sort) {
|
||||
return customFindAll ? invokeSortedFindAllReflectively(sort) : repository.findAll(sort);
|
||||
return customFindAll ? invokeFindAllReflectively(sort) : repository.findAll(sort);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -72,10 +72,10 @@ class PagingAndSortingRepositoryInvoker extends CrudRepositoryInvoker {
|
||||
*/
|
||||
@Override
|
||||
public Iterable<Object> invokeFindAll(Pageable pageable) {
|
||||
return customFindAll ? invokePagedFindAllReflectively(pageable) : repository.findAll(pageable);
|
||||
return customFindAll ? invokeFindAllReflectively(pageable) : repository.findAll(pageable);
|
||||
}
|
||||
|
||||
private boolean isRedeclaredMethod(Method method) {
|
||||
return !method.getDeclaringClass().equals(PagingAndSortingRepository.class);
|
||||
private static boolean isRedeclaredMethod(Optional<Method> method) {
|
||||
return method.map(it -> !it.getDeclaringClass().equals(PagingAndSortingRepository.class)).orElse(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker {
|
||||
*/
|
||||
@Override
|
||||
public Iterable<Object> invokeFindAll(Sort sort) {
|
||||
return invokeSortedFindAllReflectively(sort);
|
||||
return invokeFindAllReflectively(sort);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -97,7 +97,7 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker {
|
||||
*/
|
||||
@Override
|
||||
public Iterable<Object> invokeFindAll(Pageable pageable) {
|
||||
return invokePagedFindAllReflectively(pageable);
|
||||
return invokeFindAllReflectively(pageable);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -113,12 +113,12 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker {
|
||||
* @see org.springframework.data.rest.core.invoke.RepositoryInvoker#invokeSave(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T invokeSave(T object) {
|
||||
|
||||
return methods.getSaveMethod()//
|
||||
.map(it -> (T) invoke(it, object))//
|
||||
Method method = methods.getSaveMethod()//
|
||||
.orElseThrow(() -> new IllegalStateException("Repository doesn't have a save-method declared!"));
|
||||
|
||||
return invoke(method, object);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -138,9 +138,10 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker {
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T invokeFindOne(Serializable id) {
|
||||
|
||||
return methods.getFindOneMethod()//
|
||||
.map(it -> (T) invoke(it, convertId(id)))//
|
||||
Method method = methods.getFindOneMethod()//
|
||||
.orElseThrow(() -> new IllegalStateException("Repository doesn't have a find-one-method declared!"));
|
||||
|
||||
return invoke(method, convertId(id));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -262,7 +263,7 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker {
|
||||
return conversionService.convert(id, idType);
|
||||
}
|
||||
|
||||
protected Iterable<Object> invokePagedFindAllReflectively(Pageable pageable) {
|
||||
protected Iterable<Object> invokeFindAllReflectively(Pageable pageable) {
|
||||
|
||||
Method method = methods.getFindAllMethod()
|
||||
.orElseThrow(() -> new IllegalStateException("Repository doesn't have a find-all-method declared!"));
|
||||
@@ -279,7 +280,7 @@ class ReflectionRepositoryInvoker implements RepositoryInvoker {
|
||||
return invokeFindAll(pageable.getSort());
|
||||
}
|
||||
|
||||
protected Iterable<Object> invokeSortedFindAllReflectively(Sort sort) {
|
||||
protected Iterable<Object> invokeFindAllReflectively(Sort sort) {
|
||||
|
||||
Method method = methods.getFindAllMethod()
|
||||
.orElseThrow(() -> new IllegalStateException("Repository doesn't have a find-all-method declared!"));
|
||||
|
||||
@@ -110,22 +110,34 @@ public class AnnotationBasedPersistentPropertyUnitTests<P extends AnnotationBase
|
||||
|
||||
@Test // DATACMNS-243
|
||||
public void defaultsToFieldAccess() {
|
||||
assertThat(getProperty(FieldAccess.class, "name").usePropertyAccess()).isFalse();
|
||||
|
||||
assertThat(getProperty(FieldAccess.class, "name")).hasValueSatisfying(it -> {
|
||||
assertThat(it.usePropertyAccess()).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test // DATACMNS-243
|
||||
public void usesAccessTypeDeclaredOnTypeAsDefault() {
|
||||
assertThat(getProperty(PropertyAccess.class, "firstname").usePropertyAccess()).isTrue();
|
||||
|
||||
assertThat(getProperty(PropertyAccess.class, "firstname")).hasValueSatisfying(it -> {
|
||||
assertThat(it.usePropertyAccess()).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Test // DATACMNS-243
|
||||
public void propertyAnnotationOverridesTypeConfiguration() {
|
||||
assertThat(getProperty(PropertyAccess.class, "lastname").usePropertyAccess()).isFalse();
|
||||
|
||||
assertThat(getProperty(PropertyAccess.class, "lastname")).hasValueSatisfying(it -> {
|
||||
assertThat(it.usePropertyAccess()).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test // DATACMNS-243
|
||||
public void fieldAnnotationOverridesTypeConfiguration() {
|
||||
assertThat(getProperty(PropertyAccess.class, "emailAddress").usePropertyAccess()).isFalse();
|
||||
|
||||
assertThat(getProperty(PropertyAccess.class, "emailAddress")).hasValueSatisfying(it -> {
|
||||
assertThat(it.usePropertyAccess()).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test // DATACMNS-243
|
||||
@@ -135,22 +147,31 @@ public class AnnotationBasedPersistentPropertyUnitTests<P extends AnnotationBase
|
||||
|
||||
@Test // DATACMNS-534
|
||||
public void treatsNoAnnotationCorrectly() {
|
||||
assertThat(getProperty(ClassWithReadOnlyProperties.class, "noAnnotations").isWritable()).isTrue();
|
||||
|
||||
assertThat(getProperty(ClassWithReadOnlyProperties.class, "noAnnotations")).hasValueSatisfying(it -> {
|
||||
assertThat(it.isWritable()).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Test // DATACMNS-534
|
||||
public void treatsTransientAsNotExisting() {
|
||||
assertThat(getProperty(ClassWithReadOnlyProperties.class, "transientProperty")).isNull();
|
||||
assertThat(getProperty(ClassWithReadOnlyProperties.class, "transientProperty")).isEmpty();
|
||||
}
|
||||
|
||||
@Test // DATACMNS-534
|
||||
public void treatsReadOnlyAsNonWritable() {
|
||||
assertThat(getProperty(ClassWithReadOnlyProperties.class, "readOnlyProperty").isWritable()).isFalse();
|
||||
|
||||
assertThat(getProperty(ClassWithReadOnlyProperties.class, "readOnlyProperty")).hasValueSatisfying(it -> {
|
||||
assertThat(it.isWritable()).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test // DATACMNS-534
|
||||
public void considersPropertyWithReadOnlyMetaAnnotationReadOnly() {
|
||||
assertThat(getProperty(ClassWithReadOnlyProperties.class, "customReadOnlyProperty").isWritable()).isFalse();
|
||||
|
||||
assertThat(getProperty(ClassWithReadOnlyProperties.class, "customReadOnlyProperty")).hasValueSatisfying(it -> {
|
||||
assertThat(it.isWritable()).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@Test // DATACMNS-556
|
||||
@@ -162,14 +183,17 @@ public class AnnotationBasedPersistentPropertyUnitTests<P extends AnnotationBase
|
||||
@SuppressWarnings("unchecked")
|
||||
public void cachesNonPresenceOfAnnotationOnField() {
|
||||
|
||||
SamplePersistentProperty property = getProperty(Sample.class, "getterWithoutField");
|
||||
Optional<SamplePersistentProperty> property = getProperty(Sample.class, "getterWithoutField");
|
||||
|
||||
assertThat(property.findAnnotation(MyAnnotation.class)).isNotPresent();
|
||||
assertThat(property).hasValueSatisfying(it -> {
|
||||
|
||||
Map<Class<?>, ?> field = (Map<Class<?>, ?>) ReflectionTestUtils.getField(property, "annotationCache");
|
||||
assertThat(it.findAnnotation(MyAnnotation.class)).isNotPresent();
|
||||
|
||||
assertThat(field.containsKey(MyAnnotation.class)).isTrue();
|
||||
assertThat(field.get(MyAnnotation.class)).isEqualTo(Optional.empty());
|
||||
Map<Class<?>, ?> field = (Map<Class<?>, ?>) ReflectionTestUtils.getField(it, "annotationCache");
|
||||
|
||||
assertThat(field.containsKey(MyAnnotation.class)).isTrue();
|
||||
assertThat(field.get(MyAnnotation.class)).isEqualTo(Optional.empty());
|
||||
});
|
||||
}
|
||||
|
||||
@Test // DATACMNS-825
|
||||
@@ -214,8 +238,8 @@ public class AnnotationBasedPersistentPropertyUnitTests<P extends AnnotationBase
|
||||
return annotation.get();
|
||||
}
|
||||
|
||||
private SamplePersistentProperty getProperty(Class<?> type, String name) {
|
||||
return context.getRequiredPersistentEntity(type).getPersistentProperty(name).orElse(null);
|
||||
private Optional<SamplePersistentProperty> getProperty(Class<?> type, String name) {
|
||||
return context.getRequiredPersistentEntity(type).getPersistentProperty(name);
|
||||
}
|
||||
|
||||
static class Sample {
|
||||
|
||||
@@ -22,6 +22,7 @@ import rx.Observable;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -48,7 +49,7 @@ public class ReactiveRepositoryInformationUnitTests {
|
||||
|
||||
Method method = RxJava1InterfaceWithGenerics.class.getMethod("deleteAll");
|
||||
RepositoryMetadata metadata = new DefaultRepositoryMetadata(RxJava1InterfaceWithGenerics.class);
|
||||
DefaultRepositoryInformation information = new DefaultRepositoryInformation(metadata, REPOSITORY, null);
|
||||
DefaultRepositoryInformation information = new DefaultRepositoryInformation(metadata, REPOSITORY, Optional.empty());
|
||||
|
||||
Method reference = information.getTargetClassMethod(method);
|
||||
assertEquals(ReactiveCrudRepository.class, reference.getDeclaringClass());
|
||||
@@ -60,7 +61,8 @@ public class ReactiveRepositoryInformationUnitTests {
|
||||
|
||||
Method method = RxJava1InterfaceWithGenerics.class.getMethod("save", Observable.class);
|
||||
RepositoryMetadata metadata = new DefaultRepositoryMetadata(RxJava1InterfaceWithGenerics.class);
|
||||
DefaultRepositoryInformation information = new ReactiveRepositoryInformation(metadata, REPOSITORY, null);
|
||||
DefaultRepositoryInformation information = new ReactiveRepositoryInformation(metadata, REPOSITORY,
|
||||
Optional.empty());
|
||||
|
||||
Method reference = information.getTargetClassMethod(method);
|
||||
assertEquals(ReactiveCrudRepository.class, reference.getDeclaringClass());
|
||||
@@ -73,7 +75,8 @@ public class ReactiveRepositoryInformationUnitTests {
|
||||
|
||||
Method method = ReactiveSortingRepository.class.getMethod("save", Publisher.class);
|
||||
RepositoryMetadata metadata = new DefaultRepositoryMetadata(ReactiveJavaInterfaceWithGenerics.class);
|
||||
DefaultRepositoryInformation information = new ReactiveRepositoryInformation(metadata, REPOSITORY, null);
|
||||
DefaultRepositoryInformation information = new ReactiveRepositoryInformation(metadata, REPOSITORY,
|
||||
Optional.empty());
|
||||
|
||||
Method reference = information.getTargetClassMethod(method);
|
||||
assertEquals(ReactiveCrudRepository.class, reference.getDeclaringClass());
|
||||
@@ -86,7 +89,8 @@ public class ReactiveRepositoryInformationUnitTests {
|
||||
|
||||
Method method = ReactiveJavaInterfaceWithGenerics.class.getMethod("save", Iterable.class);
|
||||
RepositoryMetadata metadata = new DefaultRepositoryMetadata(ReactiveJavaInterfaceWithGenerics.class);
|
||||
DefaultRepositoryInformation information = new ReactiveRepositoryInformation(metadata, REPOSITORY, null);
|
||||
DefaultRepositoryInformation information = new ReactiveRepositoryInformation(metadata, REPOSITORY,
|
||||
Optional.empty());
|
||||
|
||||
Method reference = information.getTargetClassMethod(method);
|
||||
assertEquals(ReactiveCrudRepository.class, reference.getDeclaringClass());
|
||||
@@ -99,7 +103,8 @@ public class ReactiveRepositoryInformationUnitTests {
|
||||
|
||||
Method method = ReactiveJavaInterfaceWithGenerics.class.getMethod("save", Object.class);
|
||||
RepositoryMetadata metadata = new DefaultRepositoryMetadata(ReactiveJavaInterfaceWithGenerics.class);
|
||||
DefaultRepositoryInformation information = new ReactiveRepositoryInformation(metadata, REPOSITORY, null);
|
||||
DefaultRepositoryInformation information = new ReactiveRepositoryInformation(metadata, REPOSITORY,
|
||||
Optional.empty());
|
||||
|
||||
Method reference = information.getTargetClassMethod(method);
|
||||
assertEquals(ReactiveCrudRepository.class, reference.getDeclaringClass());
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.repository.core.support;
|
||||
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
Reference in New Issue
Block a user