diff --git a/spring-data-rest-core/pom.xml b/spring-data-rest-core/pom.xml
index 83423853e..5c3722e93 100644
--- a/spring-data-rest-core/pom.xml
+++ b/spring-data-rest-core/pom.xml
@@ -57,6 +57,12 @@
${jackson}
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jdk8
+ ${jackson}
+
+
com.google.guava
guava
@@ -73,4 +79,19 @@
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ ${source.level}
+ ${source.level}
+ -parameters
+
+
+
+
+
diff --git a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/UriToEntityConverter.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/UriToEntityConverter.java
index cdaeea02b..0c50e0415 100644
--- a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/UriToEntityConverter.java
+++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/UriToEntityConverter.java
@@ -18,6 +18,7 @@ package org.springframework.data.rest.core;
import java.net.URI;
import java.util.Collections;
import java.util.HashSet;
+import java.util.Optional;
import java.util.Set;
import org.springframework.core.convert.ConversionFailedException;
@@ -25,6 +26,7 @@ import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.data.mapping.PersistentEntity;
+import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.context.PersistentEntities;
import org.springframework.data.repository.support.Repositories;
import org.springframework.data.repository.support.RepositoryInvokerFactory;
@@ -66,9 +68,9 @@ public class UriToEntityConverter implements ConditionalGenericConverter {
for (TypeInformation> domainType : entities.getManagedTypes()) {
Class> rawType = domainType.getType();
- PersistentEntity, ?> entity = entities.getPersistentEntity(rawType);
+ Optional>> entity = entities.getPersistentEntity(rawType);
- if (entity != null && entity.hasIdProperty()) {
+ if (entity.map(it -> it.hasIdProperty()).orElse(false)) {
convertiblePairs.add(new ConvertiblePair(URI.class, domainType.getType()));
}
}
@@ -86,7 +88,7 @@ public class UriToEntityConverter implements ConditionalGenericConverter {
@Override
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return !sourceType.equals(URI_TYPE) ? false
- : repositories.getRepositoryInformationFor(targetType.getType()) != null;
+ : repositories.getRepositoryInformationFor(targetType.getType()).isPresent();
}
/*
@@ -105,9 +107,10 @@ public class UriToEntityConverter implements ConditionalGenericConverter {
@Override
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
- PersistentEntity, ?> entity = entities.getPersistentEntity(targetType.getType());
+ Optional>> entity = entities
+ .getPersistentEntity(targetType.getType());
- if (entity == null) {
+ if (!entity.isPresent()) {
throw new ConversionFailedException(sourceType, targetType, source,
new IllegalArgumentException("No PersistentEntity information available for " + targetType.getType()));
}
@@ -120,6 +123,6 @@ public class UriToEntityConverter implements ConditionalGenericConverter {
"Cannot resolve URI " + uri + ". Is it local or remote? Only local URIs are resolvable."));
}
- return invokerFactory.getInvokerFor(targetType.getType()).invokeFindOne(parts[parts.length - 1]);
+ return invokerFactory.getInvokerFor(targetType.getType()).invokeFindOne(parts[parts.length - 1]).orElse(null);
}
}
diff --git a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/ValidationErrors.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/ValidationErrors.java
index 0875f0231..5a6814056 100644
--- a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/ValidationErrors.java
+++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/ValidationErrors.java
@@ -18,6 +18,7 @@ package org.springframework.data.rest.core;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
+import java.util.Optional;
import org.springframework.beans.BeansException;
import org.springframework.beans.ConfigurablePropertyAccessor;
@@ -83,17 +84,11 @@ public class ValidationErrors extends AbstractPropertyBindingResult {
do {
String segment = iterator.next();
- PersistentEntity, ?> entity = entities.getPersistentEntity(value.getClass());
- PersistentProperty> property = entity.getPersistentProperty(PropertyAccessorUtils.getPropertyName(segment));
- if (property == null) {
- throw new NotReadablePropertyException(source.getClass(), propertyName);
- }
+ Optional extends PersistentProperty>> property = entities.getPersistentEntity(value.getClass())//
+ .flatMap(it -> it.getPersistentProperty(PropertyAccessorUtils.getPropertyName(segment)));
- ConfigurablePropertyAccessor accessor = property.usePropertyAccess()
- ? PropertyAccessorFactory.forBeanPropertyAccess(value)
- : PropertyAccessorFactory.forDirectFieldAccess(value);
- value = accessor.getPropertyValue(segment);
+ value = getValue(value, property, segment, propertyName);
} while (iterator.hasNext());
@@ -110,4 +105,18 @@ public class ValidationErrors extends AbstractPropertyBindingResult {
public Object getTarget() {
return source;
}
+
+ private static Object getValue(Object source, Optional extends PersistentProperty>> property, String segment,
+ String name) {
+
+ return property.map(it -> {
+
+ ConfigurablePropertyAccessor accessor = it.usePropertyAccess()
+ ? PropertyAccessorFactory.forBeanPropertyAccess(source)
+ : PropertyAccessorFactory.forDirectFieldAccess(source);
+
+ return accessor.getPropertyValue(segment);
+
+ }).orElseThrow(() -> new NotReadablePropertyException(source.getClass(), name));
+ }
}
diff --git a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/EntityLookupConfiguration.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/EntityLookupConfiguration.java
index b1e17e3bd..fb8a02e4d 100644
--- a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/EntityLookupConfiguration.java
+++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/EntityLookupConfiguration.java
@@ -22,6 +22,7 @@ import lombok.Value;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.repository.Repository;
@@ -188,11 +189,15 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
Assert.notNull(repositories, "Repositories must not be null!");
Assert.notNull(lookupInformation, "LookupInformation must not be null!");
- RepositoryInformation information = repositories.getRepositoryInformation(lookupInformation.repositoryType);
+ RepositoryInformation information = repositories.getRepositoryInformation(lookupInformation.repositoryType)//
+ .orElseThrow(() -> new IllegalStateException(
+ "No repository found for type " + lookupInformation.repositoryType.getName() + "!"));
- this.repository = (Repository extends T, ?>) repositories.getRepositoryFor(information.getDomainType());
this.domainType = information.getDomainType();
this.lookupInfo = lookupInformation;
+ this.repository = (Repository extends T, ?>) repositories.getRepositoryFor(information.getDomainType())//
+ .orElseThrow(() -> new IllegalStateException(
+ "No repository found for type " + information.getDomainType().getName() + "!"));
}
/*
@@ -209,8 +214,8 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
* @see org.springframework.data.rest.core.support.EntityLookup#lookupEntity(java.io.Serializable)
*/
@Override
- public Object lookupEntity(Serializable id) {
- return lookupInfo.getLookup().lookup(repository, id);
+ public Optional