DATACMNS-1101 - Reduce Optional usage in convert/mapping packages.

Reducing Optional usage that lies on hot code paths for object mapping.
This commit is contained in:
Mark Paluch
2017-06-26 15:49:47 +02:00
committed by Oliver Gierke
parent 4aa083377b
commit 74fbe13f54
42 changed files with 428 additions and 427 deletions

View File

@@ -38,7 +38,7 @@ import org.springframework.util.Assert;
* {@link AuditableBeanWrapperFactory} that will create am {@link AuditableBeanWrapper} using mapping information
* obtained from a {@link MappingContext} to detect auditing configuration and eventually invoking setting the auditing
* values.
*
*
* @author Oliver Gierke
* @author Christoph Strobl
* @since 1.8
@@ -50,7 +50,7 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap
/**
* Creates a new {@link MappingAuditableBeanWrapperFactory} using the given {@link PersistentEntities}.
*
*
* @param entities must not be {@literal null}.
*/
public MappingAuditableBeanWrapperFactory(PersistentEntities entities) {
@@ -61,7 +61,7 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap
this.metadataCache = new HashMap<>();
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.auditing.AuditableBeanWrapperFactory#getBeanWrapperFor(java.lang.Object)
*/
@@ -90,7 +90,7 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap
/**
* Captures {@link PersistentProperty} instances equipped with auditing annotations.
*
*
* @author Oliver Gierke
* @since 1.8
*/
@@ -101,7 +101,7 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap
/**
* Creates a new {@link MappingAuditingMetadata} instance from the given {@link PersistentEntity}.
*
*
* @param entity must not be {@literal null}.
*/
public MappingAuditingMetadata(PersistentEntity<?, ? extends PersistentProperty<?>> entity) {
@@ -117,7 +117,7 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap
/**
* Returns whether the {@link PersistentEntity} is auditable at all (read: any of the auditing annotations is
* present).
*
*
* @return
*/
public boolean isAuditable() {
@@ -129,7 +129,7 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap
/**
* {@link AuditableBeanWrapper} using {@link MappingAuditingMetadata} and a {@link PersistentPropertyAccessor} to set
* values on auditing properties.
*
*
* @author Oliver Gierke
* @since 1.8
*/
@@ -141,32 +141,32 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap
/**
* Creates a new {@link MappingMetadataAuditableBeanWrapper} for the given target and
* {@link MappingAuditingMetadata}.
*
* @param target must not be {@literal null}.
*
* @param accessor must not be {@literal null}.
* @param metadata must not be {@literal null}.
*/
public MappingMetadataAuditableBeanWrapper(PersistentPropertyAccessor accessor, MappingAuditingMetadata metadata) {
Assert.notNull(accessor, "Target object must not be null!");
Assert.notNull(accessor, "PersistentPropertyAccessor must not be null!");
Assert.notNull(metadata, "Auditing metadata must not be null!");
this.accessor = accessor;
this.metadata = metadata;
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.auditing.AuditableBeanWrapper#setCreatedBy(java.util.Optional)
*/
@Override
public Object setCreatedBy(Object value) {
metadata.createdByProperty.ifPresent(it -> this.accessor.setProperty(it, Optional.of(value)));
metadata.createdByProperty.ifPresent(it -> this.accessor.setProperty(it, value));
return value;
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.auditing.AuditableBeanWrapper#setCreatedDate(java.util.Optional)
*/
@@ -175,7 +175,7 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap
return setDateProperty(metadata.createdDateProperty, value);
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.auditing.AuditableBeanWrapper#setLastModifiedBy(java.util.Optional)
*/
@@ -184,17 +184,17 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap
return setProperty(metadata.lastModifiedByProperty, value);
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.auditing.AuditableBeanWrapper#getLastModifiedDate()
*/
@Override
public Optional<TemporalAccessor> getLastModifiedDate() {
return getAsTemporalAccessor(metadata.lastModifiedDateProperty.flatMap(accessor::getProperty),
return getAsTemporalAccessor(metadata.lastModifiedDateProperty.map(accessor::getProperty),
LocalDateTime.class);
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.auditing.AuditableBeanWrapper#setLastModifiedDate(java.util.Optional)
*/
@@ -214,7 +214,7 @@ public class MappingAuditableBeanWrapperFactory extends DefaultAuditableBeanWrap
TemporalAccessor value) {
property.ifPresent(
it -> this.accessor.setProperty(it, Optional.of(getDateValueToSet(value, it.getType(), accessor.getBean()))));
it -> this.accessor.setProperty(it, getDateValueToSet(value, it.getType(), accessor.getBean())));
return value;
}

View File

@@ -49,6 +49,7 @@ import org.springframework.util.ClassUtils;
* @author Oliver Gierke
* @author Phillip Webb
* @author Christoph Strobl
* @author Mark Paluch
* @since 1.11
*/
public class ClassGeneratingEntityInstantiator implements EntityInstantiator {
@@ -64,7 +65,7 @@ public class ClassGeneratingEntityInstantiator implements EntityInstantiator {
this.generator = new ObjectInstantiatorClassGenerator();
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.convert.EntityInstantiator#createInstance(org.springframework.data.mapping.PersistentEntity, org.springframework.data.mapping.model.ParameterValueProvider)
*/
@@ -196,7 +197,7 @@ public class ClassGeneratingEntityInstantiator implements EntityInstantiator {
try {
return (T) instantiator.newInstance(params);
} catch (Exception e) {
throw new MappingInstantiationException(Optional.of(entity), Arrays.asList(params), e);
throw new MappingInstantiationException(entity, Arrays.asList(params), e);
}
}
@@ -218,7 +219,6 @@ public class ClassGeneratingEntityInstantiator implements EntityInstantiator {
return it.getParameters().stream()//
.map(provider::getParameterValue)//
.map(value -> value.orElse(null))//
.toArray();
}).orElse(EMPTY_ARRAY);
@@ -227,7 +227,7 @@ public class ClassGeneratingEntityInstantiator implements EntityInstantiator {
/**
* Needs to be public as otherwise the implementation class generated does not see the interface from the classloader.
*
*
* @author Thomas Darimont
* @author Oliver Gierke
*/

View File

@@ -19,23 +19,22 @@ import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.springframework.beans.BeanInstantiationException;
import org.springframework.beans.BeanUtils;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PreferredConstructor;
import org.springframework.data.mapping.PreferredConstructor.Parameter;
import org.springframework.data.mapping.model.MappingInstantiationException;
import org.springframework.data.mapping.model.ParameterValueProvider;
/**
* {@link EntityInstantiator} that uses the {@link PersistentEntity}'s {@link PreferredConstructor} to instantiate an
* instance of the entity via reflection.
*
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Mark Paluch
*/
public enum ReflectionEntityInstantiator implements EntityInstantiator {
@@ -45,51 +44,39 @@ public enum ReflectionEntityInstantiator implements EntityInstantiator {
public <T, E extends PersistentEntity<? extends T, P>, P extends PersistentProperty<P>> T createInstance(E entity,
ParameterValueProvider<P> provider) {
return entity.getPersistenceConstructor().map(constructor -> {
PreferredConstructor<? extends T, P> constructor = entity.getPersistenceConstructor().orElse(null);
List<Object> params = Optional.ofNullable(provider)//
.map(it -> constructor.getParameters().stream()//
.map(parameter -> it.getParameterValue(parameter).orElse(Optional.empty()))//
.collect(Collectors.toList()))//
.orElseGet(Collections::emptyList);
List<Object> foo = new ArrayList<>(params.size());
for (Object element : params) {
foo.add((element instanceof Optional) ? null : element);
}
if (constructor == null) {
try {
return (T) BeanUtils.instantiateClass(constructor.getConstructor(), foo.toArray());
} catch (BeanInstantiationException e) {
throw new MappingInstantiationException(Optional.of(entity), params, e);
}
}).orElseGet(() -> {
try {
Class<? extends T> clazz = entity.getType();
Class<?> clazz = entity.getType();
if (clazz.isArray()) {
Class<?> ctype = clazz;
int dims = 0;
while (ctype.isArray()) {
ctype = ctype.getComponentType();
dims++;
}
return (T) Array.newInstance(clazz, dims);
} else {
return BeanUtils.instantiateClass(clazz);
return BeanUtils.instantiateClass(entity.getType());
}
} catch (BeanInstantiationException e) {
throw new MappingInstantiationException(Optional.of(entity), Collections.emptyList(), e);
throw new MappingInstantiationException(entity, Collections.emptyList(), e);
}
});
}
List<Object> params = new ArrayList<>();
if (null != provider && constructor.hasParameters()) {
for (Parameter<?, P> parameter : constructor.getParameters()) {
params.add(provider.getParameterValue(parameter));
}
}
try {
return BeanUtils.instantiateClass(constructor.getConstructor(), params.toArray());
} catch (BeanInstantiationException e) {
throw new MappingInstantiationException(entity, params, e);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-2017 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.
@@ -15,33 +15,39 @@
*/
package org.springframework.data.mapping;
import java.util.Optional;
/**
* Interface for a component allowing the access of identifier values.
*
*
* @author Oliver Gierke
* @author Mark Paluch
* @see TargetAwareIdentifierAccessor
*/
public interface IdentifierAccessor {
/**
* Returns the value of the identifier.
*
*
* @return the identifier of the underlying instance.
*/
Optional<Object> getIdentifier();
Object getIdentifier();
/**
* Returns the identifier of the underlying instance. Implementations are strongly recommended to extends either
* {@link TargetAwareIdentifierAccessor} or override this method to add more context to the exception being thrown in
* case of the absence of an identifier.
*
*
* @return the identifier of the underlying instance
* @throws IllegalStateException in case no identifier could be retrieved.
* @since 2.0
*/
default Object getRequiredIdentifier() {
return getIdentifier().orElseThrow(() -> new IllegalStateException(String.format("Could not obtain identifier!")));
Object identifier = getIdentifier();
if (identifier != null) {
return identifier;
}
throw new IllegalStateException("Could not obtain identifier!");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014-2017 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.
@@ -15,15 +15,13 @@
*/
package org.springframework.data.mapping;
import java.util.Optional;
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
/**
* Domain service to allow accessing and setting {@link PersistentProperty}s of an entity. Usually obtained through
* {@link PersistentEntity#getPropertyAccessor(Object)}. In case type conversion shall be applied on property access,
* use a {@link ConvertingPropertyAccessor}.
*
*
* @author Oliver Gierke
* @since 1.10
* @see PersistentEntity#getPropertyAccessor(Object)
@@ -34,26 +32,25 @@ public interface PersistentPropertyAccessor {
/**
* Sets the given {@link PersistentProperty} to the given value. Will do type conversion if a
* {@link org.springframework.core.convert.ConversionService} is configured.
*
*
* @param property must not be {@literal null}.
* @param value can be {@literal null}.
* @throws org.springframework.data.mapping.model.MappingException in case an exception occurred when setting the
* property value.
*/
void setProperty(PersistentProperty<?> property, Optional<? extends Object> value);
void setProperty(PersistentProperty<?> property, Object value);
/**
* Returns the value of the given {@link PersistentProperty} of the underlying bean instance.
*
* @param <S>
*
* @param property must not be {@literal null}.
* @return can be {@literal null}.
*/
Optional<Object> getProperty(PersistentProperty<?> property);
Object getProperty(PersistentProperty<?> property);
/**
* Returns the underlying bean.
*
*
* @return will never be {@literal null}.
*/
Object getBean();

View File

@@ -22,8 +22,9 @@ import java.util.function.Supplier;
/**
* {@link IdentifierAccessor} that is aware of the target bean to obtain the identifier from so that it can generate a
* more meaningful exception in case of an absent identifier and a call to {@link #getRequiredIdentifier()}.
*
*
* @author Oliver Gierke
* @author Mark Paluch
* @since 2.0
* @soundtrack Anika Nilles - Greenfield (Pikalar)
*/
@@ -32,13 +33,19 @@ public abstract class TargetAwareIdentifierAccessor implements IdentifierAccesso
private final Supplier<Object> target;
/*
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.IdentifierAccessor#getRequiredIdentifier()
*/
@Override
public Object getRequiredIdentifier() {
return getIdentifier().orElseThrow(
() -> new IllegalStateException(String.format("Could not obtain identifier from %s!", target.get())));
Object identifier = getIdentifier();
if (identifier != null) {
return identifier;
}
throw new IllegalStateException(String.format("Could not obtain identifier from %s!", target.get()));
}
}

View File

@@ -67,8 +67,8 @@ import org.springframework.util.StringUtils;
* The implementation uses a {@link ReentrantReadWriteLock} to make sure {@link PersistentEntity} are completely
* populated before accessing them from outside.
*
* @param E the concrete {@link PersistentEntity} type the {@link MappingContext} implementation creates
* @param P the concrete {@link PersistentProperty} type the {@link MappingContext} implementation creates
* @param <E> the concrete {@link PersistentEntity} type the {@link MappingContext} implementation creates
* @param <P> the concrete {@link PersistentProperty} type the {@link MappingContext} implementation creates
* @author Jon Brisbin
* @author Oliver Gierke
* @author Michael Hunger
@@ -164,7 +164,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
return getPersistentEntity(ClassTypeInformation.from(type));
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.context.MappingContext#getRequiredPersistentEntity(java.lang.Class)
*/
@@ -228,7 +228,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
return addPersistentEntity(type);
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.context.MappingContext#getRequiredPersistentEntity(org.springframework.data.util.TypeInformation)
*/
@@ -251,7 +251,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
return getPersistentEntity(typeInfo.getActualType());
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.context.MappingContext#getRequiredPersistentEntity(org.springframework.data.mapping.PersistentProperty)
*/
@@ -457,8 +457,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
/**
* Creates the concrete instance of {@link PersistentProperty}.
*
* @param field
* @param descriptor
* @param property
* @param owner
* @param simpleTypeHolder
* @return
@@ -606,7 +605,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
/**
* Returns whether the given {@link PropertyDescriptor} is one to create a {@link PersistentProperty} for.
*
* @param descriptor must not be {@literal null}.
* @param property must not be {@literal null}.
* @return
*/
public boolean matches(Property property) {
@@ -650,7 +649,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
/**
* Returns whether the given {@link Field} matches the defined {@link PropertyMatch}.
*
* @param field must not be {@literal null}.
* @param name must not be {@literal null}.
* @return
*/
public boolean matches(String name, Class<?> type) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2017 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.
@@ -27,35 +27,44 @@ import org.springframework.data.util.TypeInformation;
* This interface defines the overall context including all known PersistentEntity instances and methods to obtain
* instances on demand. it is used internally to establish associations between entities and also at runtime to obtain
* entities by name.
*
*
* @author Oliver Gierke
* @author Jon Brisbin
* @author Graeme Rocher
* @author Mark Paluch
*/
public interface MappingContext<E extends PersistentEntity<?, P>, P extends PersistentProperty<P>> {
/**
* Returns all {@link PersistentEntity}s held in the context.
*
*
* @return
*/
Collection<E> getPersistentEntities();
/**
* Returns a {@link PersistentEntity} for the given {@link Class}. Will return {@literal null} for types that are
* considered simple ones.
*
* Returns a {@link PersistentEntity} for the given {@link Class}. Will return {@link Optional#empty()} for types that
* are considered simple ones.
*
* @see org.springframework.data.mapping.model.SimpleTypeHolder#isSimpleType(Class)
* @param type must not be {@literal null}.
* @return
*/
Optional<E> getPersistentEntity(Class<?> type);
/**
* Returns a required {@link PersistentEntity} for the given {@link Class}. Will throw
* {@link IllegalArgumentException} for types that are considered simple ones.
*
* @see org.springframework.data.mapping.model.SimpleTypeHolder#isSimpleType(Class)
* @param type must not be {@literal null}.
* @return
*/
E getRequiredPersistentEntity(Class<?> type);
/**
* Returns whether the {@link MappingContext} currently contains a {@link PersistentEntity} for the type.
*
*
* @param type must not be {@literal null}.
* @return
* @since 1.8
@@ -63,20 +72,28 @@ public interface MappingContext<E extends PersistentEntity<?, P>, P extends Pers
boolean hasPersistentEntityFor(Class<?> type);
/**
* Returns a {@link PersistentEntity} for the given {@link TypeInformation}. Will return {@literal null} for types
* that are considered simple ones.
*
* Returns a {@link PersistentEntity} for the given {@link TypeInformation}. Will return {@link Optional#empty()} for
* types that are considered simple ones.
*
* @see org.springframework.data.mapping.model.SimpleTypeHolder#isSimpleType(Class)
* @param type must not be {@literal null}.
* @return
*/
Optional<E> getPersistentEntity(TypeInformation<?> type);
/**
* Returns a {@link PersistentEntity} for the given {@link TypeInformation}. Will throw
* {@link IllegalArgumentException} for types that are considered simple ones.
*
* @see org.springframework.data.mapping.model.SimpleTypeHolder#isSimpleType(Class)
* @param type must not be {@literal null}.
* @return
*/
E getRequiredPersistentEntity(TypeInformation<?> type);
/**
* Returns the {@link PersistentEntity} mapped by the given {@link PersistentProperty}.
*
*
* @param persistentProperty must not be {@literal null}.
* @return the {@link PersistentEntity} mapped by the given {@link PersistentProperty} or null if no
* {@link PersistentEntity} exists for it or the {@link PersistentProperty} does not refer to an entity (the
@@ -85,11 +102,20 @@ public interface MappingContext<E extends PersistentEntity<?, P>, P extends Pers
*/
Optional<E> getPersistentEntity(P persistentProperty);
/**
* Returns the {@link PersistentEntity} mapped by the given {@link PersistentProperty}.
*
* @param persistentProperty must not be {@literal null}.
* @return the {@link PersistentEntity} mapped by the given {@link PersistentProperty} or null if no
* {@link PersistentEntity} exists for it or the {@link PersistentProperty} does not refer to an entity (the
* type of the property is considered simple see
* {@link org.springframework.data.mapping.model.SimpleTypeHolder#isSimpleType(Class)}).
*/
E getRequiredPersistentEntity(P persistentProperty);
/**
* Returns all {@link PersistentProperty}s for the given path expression based on the given {@link PropertyPath}.
*
*
* @param propertyPath must not be {@literal null}.
* @return the {@link PersistentPropertyPath} representing the given {@link PropertyPath}.
* @throws InvalidPersistentPropertyPath in case not all of the segments of the given {@link PropertyPath} can be
@@ -99,7 +125,7 @@ public interface MappingContext<E extends PersistentEntity<?, P>, P extends Pers
/**
* Returns all {@link PersistentProperty}s for the given dot path notation based on the given type.
*
*
* @param propertyPath must not be {@literal null}.
* @param type must not be {@literal null}.
* @return the {@link PersistentPropertyPath} representing the given property path on the given type.
@@ -110,7 +136,7 @@ public interface MappingContext<E extends PersistentEntity<?, P>, P extends Pers
/**
* Returns the {@link PersistentPropertyPath} for the resolvable part of the given
* {@link InvalidPersistentPropertyPath}.
*
*
* @param invalidPath must not be {@literal null}.
* @return the {@link PersistentPropertyPath} for the resolvable part of the given
* {@link InvalidPersistentPropertyPath}.
@@ -120,7 +146,7 @@ public interface MappingContext<E extends PersistentEntity<?, P>, P extends Pers
/**
* Returns the {@link TypeInformation}s for all {@link PersistentEntity}s in the {@link MappingContext}.
*
*
* @return all {@link TypeInformation}s for the {@link PersistentEntity}s in the {@link MappingContext}.
* @since 1.8
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2015 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.
@@ -33,11 +33,11 @@ import org.springframework.util.Assert;
/**
* An {@link IsNewStrategyFactory} using a {@link MappingContext} to determine the {@link IsNewStrategy} to be returned
* for a particular type. It will look for a version and id property on the {@link PersistentEntity} and return a
* strategy instance that will refelctively inspect the property for {@literal null} values or {@literal null} or a
* strategy instance that will reflectively inspect the property for {@literal null} values or {@literal null} or a
* value of 0 in case of a version property.
*
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Mark Paluch
*/
public class MappingContextIsNewStrategyFactory extends IsNewStrategyFactorySupport {
@@ -45,7 +45,7 @@ public class MappingContextIsNewStrategyFactory extends IsNewStrategyFactorySupp
/**
* Creates a new {@link MappingContextIsNewStrategyFactory} using the given {@link MappingContext}.
*
*
* @param context must not be {@literal null}.
* @deprecated use {@link MappingContextIsNewStrategyFactory(PersistentEntities)} instead.
*/
@@ -56,8 +56,8 @@ public class MappingContextIsNewStrategyFactory extends IsNewStrategyFactorySupp
/**
* Creates a new {@link MappingContextIsNewStrategyFactory} using the given {@link PersistentEntities}.
*
* @param context must not be {@literal null}.
*
* @param entities must not be {@literal null}.
* @since 1.10
*/
public MappingContextIsNewStrategyFactory(PersistentEntities entities) {
@@ -74,11 +74,11 @@ public class MappingContextIsNewStrategyFactory extends IsNewStrategyFactorySupp
protected IsNewStrategy doGetIsNewStrategy(Class<?> type) {
return context.getPersistentEntity(type)//
.flatMap(MappingContextIsNewStrategyFactory::foo)//
.flatMap(MappingContextIsNewStrategyFactory::getIsNewStrategy)//
.orElseThrow(() -> new MappingException(String.format("Cannot determine IsNewStrategy for type %s!", type)));
}
private static Optional<IsNewStrategy> foo(PersistentEntity<?, ?> entity) {
private static Optional<IsNewStrategy> getIsNewStrategy(PersistentEntity<?, ?> entity) {
if (entity.hasVersionProperty()) {
@@ -96,15 +96,15 @@ public class MappingContextIsNewStrategyFactory extends IsNewStrategyFactorySupp
/**
* {@link IsNewStrategy} implementation that will inspect a given {@link PersistentProperty} and call
* {@link #decideIsNew(Object)} with the value retrieved by reflection.
*
* {@link #isNew(Object)} with the value retrieved by reflection.
*
* @author Oliver Gierke
*/
@RequiredArgsConstructor(staticName = "of")
static class PersistentPropertyInspectingIsNewStrategy implements IsNewStrategy {
private final @NonNull PersistentProperty<?> property;
private final @NonNull Function<Optional<Object>, Boolean> isNew;
private final @NonNull Function<Object, Boolean> isNew;
/*
* (non-Javadoc)
@@ -119,20 +119,11 @@ public class MappingContextIsNewStrategyFactory extends IsNewStrategyFactorySupp
}
}
private static boolean propertyIsNull(Optional<Object> it) {
return !it.isPresent();
private static boolean propertyIsNull(Object it) {
return it == null;
}
private static boolean propertyIsNullOrZeroNumber(Optional<Object> it) {
return it.map(value -> {
if (!(value instanceof Number)) {
return false;
}
return ((Number) value).longValue() == 0;
}).orElse(true);
private static boolean propertyIsNullOrZeroNumber(Object value) {
return propertyIsNull(value) || value instanceof Number && ((Number) value).longValue() == 0;
}
}

View File

@@ -36,11 +36,12 @@ import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
/**
* Simple impementation of {@link PersistentProperty}.
*
* Simple implementation of {@link PersistentProperty}.
*
* @author Jon Brisbin
* @author Oliver Gierke
* @author Christoph Strobl
* @author Mark Paluch
*/
public abstract class AbstractPersistentProperty<P extends PersistentProperty<P>> implements PersistentProperty<P> {
@@ -121,7 +122,7 @@ public abstract class AbstractPersistentProperty<P extends PersistentProperty<P>
return information;
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.PersistentProperty#getPersistentEntityType()
*/
@@ -133,11 +134,11 @@ public abstract class AbstractPersistentProperty<P extends PersistentProperty<P>
}
return entityTypeInformation.get()//
.map(it -> Collections.singleton(it))//
.orElseGet(() -> Collections.emptySet());
.map(Collections::singleton)//
.orElseGet(Collections::emptySet);
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.PersistentProperty#getGetter()
*/
@@ -146,7 +147,7 @@ public abstract class AbstractPersistentProperty<P extends PersistentProperty<P>
return property.getGetter();
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.PersistentProperty#getSetter()
*/
@@ -268,7 +269,7 @@ public abstract class AbstractPersistentProperty<P extends PersistentProperty<P>
return isMap() ? information.getMapValueType().map(TypeInformation::getType) : Optional.empty();
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.PersistentProperty#getActualType()
*/
@@ -277,7 +278,7 @@ public abstract class AbstractPersistentProperty<P extends PersistentProperty<P>
return information.getActualType().getType();
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#usePropertyAccess()
*/
@@ -285,7 +286,7 @@ public abstract class AbstractPersistentProperty<P extends PersistentProperty<P>
return usePropertyAccess.get();
}
/*
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@@ -305,7 +306,7 @@ public abstract class AbstractPersistentProperty<P extends PersistentProperty<P>
return this.property.equals(that.property);
}
/*
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@@ -314,7 +315,7 @@ public abstract class AbstractPersistentProperty<P extends PersistentProperty<P>
return this.hashCode.get();
}
/*
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/

View File

@@ -17,7 +17,6 @@ package org.springframework.data.mapping.model;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@@ -99,7 +98,7 @@ public abstract class AnnotationBasedPersistentProperty<P extends PersistentProp
annotationType.getSimpleName(), getName(), getOwner().getType().getSimpleName());
annotationCache.put(annotationType,
Optional.of(AnnotatedElementUtils.findMergedAnnotation(it, annotationType)));
Optional.ofNullable(AnnotatedElementUtils.findMergedAnnotation(it, annotationType)));
}
});
@@ -114,7 +113,7 @@ public abstract class AnnotationBasedPersistentProperty<P extends PersistentProp
annotationType.getSimpleName(), it.getName(), getOwner().getType().getSimpleName());
annotationCache.put(annotationType,
Optional.of(AnnotatedElementUtils.findMergedAnnotation(it, annotationType)));
Optional.ofNullable(AnnotatedElementUtils.findMergedAnnotation(it, annotationType)));
}
});
}
@@ -156,7 +155,7 @@ public abstract class AnnotationBasedPersistentProperty<P extends PersistentProp
* Considers plain transient fields, fields annotated with {@link Transient}, {@link Value} or {@link Autowired} as
* transient.
*
* @see org.springframework.data.mapping.BasicPersistentProperty#isTransient()
* @see org.springframework.data.mapping.PersistentProperty#isTransient()
*/
@Override
public boolean isTransient() {
@@ -239,10 +238,7 @@ public abstract class AnnotationBasedPersistentProperty<P extends PersistentProp
*/
private <A extends Annotation> Optional<A> cacheAndReturn(Class<? extends A> type, Optional<A> annotation) {
if (annotationCache != null) {
annotationCache.put(type, annotation);
}
annotationCache.put(type, annotation);
return annotation;
}
@@ -277,7 +273,7 @@ public abstract class AnnotationBasedPersistentProperty<P extends PersistentProp
}
String builder = annotationCache.values().stream() //
.flatMap(it -> Optionals.toStream(it)) //
.flatMap(Optionals::toStream) //
.map(Object::toString) //
.collect(Collectors.joining(" "));
@@ -285,6 +281,6 @@ public abstract class AnnotationBasedPersistentProperty<P extends PersistentProp
}
private Stream<Optional<? extends AnnotatedElement>> getAccessors() {
return Arrays.<Optional<? extends AnnotatedElement>> asList(getGetter(), getSetter(), getField()).stream();
return Stream.of(getGetter(), getSetter(), getField());
}
}

View File

@@ -35,18 +35,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.data.annotation.TypeAlias;
import org.springframework.data.mapping.Alias;
import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.AssociationHandler;
import org.springframework.data.mapping.IdentifierAccessor;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.PreferredConstructor;
import org.springframework.data.mapping.PropertyHandler;
import org.springframework.data.mapping.SimpleAssociationHandler;
import org.springframework.data.mapping.SimplePropertyHandler;
import org.springframework.data.mapping.TargetAwareIdentifierAccessor;
import org.springframework.data.mapping.*;
import org.springframework.data.util.Lazy;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.Assert;
@@ -74,7 +63,7 @@ public class BasicPersistentEntity<T, P extends PersistentProperty<P>> implement
private final Optional<Comparator<P>> comparator;
private final Set<Association<P>> associations;
private final Map<String, P> propertyCache;
private final Map<String, Optional<P>> propertyCache;
private final Map<Class<? extends Annotation>, Optional<Annotation>> annotationCache;
private Optional<P> idProperty = Optional.empty();
@@ -208,7 +197,7 @@ public class BasicPersistentEntity<T, P extends PersistentProperty<P>> implement
properties.add(property);
if (!propertyCache.containsKey(property.getName())) {
propertyCache.put(property.getName(), property);
propertyCache.put(property.getName(), Optional.of(property));
}
P candidate = returnPropertyIfBetterIdPropertyCandidateOrNull(property);
@@ -268,7 +257,14 @@ public class BasicPersistentEntity<T, P extends PersistentProperty<P>> implement
* @see org.springframework.data.mapping.PersistentEntity#getPersistentProperty(java.lang.String)
*/
public Optional<P> getPersistentProperty(String name) {
return Optional.ofNullable(propertyCache.get(name));
Optional<P> property = propertyCache.get(name);
if (property != null) {
return property;
}
return Optional.empty();
}
/*
@@ -467,8 +463,8 @@ public class BasicPersistentEntity<T, P extends PersistentProperty<P>> implement
* @see org.springframework.data.mapping.IdentifierAccessor#getIdentifier()
*/
@Override
public Optional<Object> getIdentifier() {
return Optional.empty();
public Object getIdentifier() {
return null;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 by the original author(s).
* Copyright 2011-2017 by the original author(s).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,8 +26,9 @@ import org.springframework.util.ReflectionUtils;
/**
* Domain service to allow accessing the values of {@link PersistentProperty}s on a given bean.
*
*
* @author Oliver Gierke
* @author Mark Paluch
*/
class BeanWrapper<T> implements PersistentPropertyAccessor {
@@ -35,7 +36,7 @@ class BeanWrapper<T> implements PersistentPropertyAccessor {
/**
* Creates a new {@link BeanWrapper} for the given bean.
*
*
* @param bean must not be {@literal null}.
*/
protected BeanWrapper(T bean) {
@@ -48,7 +49,7 @@ class BeanWrapper<T> implements PersistentPropertyAccessor {
* (non-Javadoc)
* @see org.springframework.data.mapping.PersistentPropertyAccessor#setProperty(org.springframework.data.mapping.PersistentProperty, java.util.Optional)
*/
public void setProperty(PersistentProperty<?> property, Optional<? extends Object> value) {
public void setProperty(PersistentProperty<?> property, Object value) {
Assert.notNull(property, "PersistentProperty must not be null!");
@@ -59,7 +60,7 @@ class BeanWrapper<T> implements PersistentPropertyAccessor {
Field field = property.getField().get();
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field, bean, value.orElse(null));
ReflectionUtils.setField(field, bean, value);
return;
}
@@ -68,7 +69,7 @@ class BeanWrapper<T> implements PersistentPropertyAccessor {
setter.ifPresent(it -> {
ReflectionUtils.makeAccessible(it);
ReflectionUtils.invokeMethod(it, bean, value.orElse(null));
ReflectionUtils.invokeMethod(it, bean, value);
});
} catch (IllegalStateException e) {
@@ -80,13 +81,13 @@ class BeanWrapper<T> implements PersistentPropertyAccessor {
* (non-Javadoc)
* @see org.springframework.data.mapping.PersistentPropertyAccessor#getProperty(org.springframework.data.mapping.PersistentProperty)
*/
public Optional<Object> getProperty(PersistentProperty<?> property) {
public Object getProperty(PersistentProperty<?> property) {
return getProperty(property, property.getType());
}
/**
* Returns the value of the given {@link PersistentProperty} potentially converted to the given type.
*
*
* @param <S>
* @param property must not be {@literal null}.
* @param type can be {@literal null}.
@@ -94,7 +95,7 @@ class BeanWrapper<T> implements PersistentPropertyAccessor {
* @throws MappingException in case an exception occured when accessing the property.
*/
@SuppressWarnings("unchecked")
public <S> Optional<S> getProperty(PersistentProperty<?> property, Class<? extends S> type) {
public <S> Object getProperty(PersistentProperty<?> property, Class<? extends S> type) {
Assert.notNull(property, "PersistentProperty must not be null!");
@@ -104,7 +105,7 @@ class BeanWrapper<T> implements PersistentPropertyAccessor {
Field field = property.getField().get();
ReflectionUtils.makeAccessible(field);
return Optional.ofNullable((S) ReflectionUtils.getField(field, bean));
return ReflectionUtils.getField(field, bean);
}
Optional<Method> getter = property.getGetter();
@@ -113,7 +114,7 @@ class BeanWrapper<T> implements PersistentPropertyAccessor {
ReflectionUtils.makeAccessible(it);
return (S) ReflectionUtils.invokeMethod(it, bean);
});
}).orElse(null);
} catch (IllegalStateException e) {
throw new MappingException(

View File

@@ -260,7 +260,6 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
private static final String JAVA_LANG_REFLECT_METHOD = "java/lang/reflect/Method";
private static final String JAVA_LANG_INVOKE_METHOD_HANDLE = "java/lang/invoke/MethodHandle";
private static final String JAVA_LANG_CLASS = "java/lang/Class";
private static final String JAVA_UTIL_OPTIONAL = "java/util/Optional";
private static final String BEAN_FIELD = "bean";
private static final String THIS_REF = "this";
private static final String PERSISTENT_PROPERTY = "org/springframework/data/mapping/PersistentProperty";
@@ -707,8 +706,8 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
List<PersistentProperty<?>> persistentProperties, String internalClassName, ClassWriter cw) {
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "getProperty",
"(Lorg/springframework/data/mapping/PersistentProperty;)Ljava/util/Optional;",
"(Lorg/springframework/data/mapping/PersistentProperty<*>;)Ljava/util/Optional<+Ljava/lang/Object;>;", null);
"(Lorg/springframework/data/mapping/PersistentProperty;)Ljava/lang/Object;",
"(Lorg/springframework/data/mapping/PersistentProperty<*>;)Ljava/lang/Object;", null);
mv.visitCode();
Label l0 = new Label();
@@ -849,13 +848,11 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
return null;
});
mv.visitMethodInsn(INVOKESTATIC, JAVA_UTIL_OPTIONAL, "ofNullable",
String.format("(%s)%s", referenceName(JAVA_LANG_OBJECT), referenceName(JAVA_UTIL_OPTIONAL)), false);
mv.visitInsn(ARETURN);
}
/**
* Generate the {@link PersistentPropertyAccessor#setProperty(PersistentProperty, Optional)} method. *
* Generate the {@link PersistentPropertyAccessor#setProperty(PersistentProperty, Object)} method. *
*
* <pre>
* {
@@ -878,15 +875,14 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
List<PersistentProperty<?>> persistentProperties, String internalClassName, ClassWriter cw) {
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "setProperty",
"(Lorg/springframework/data/mapping/PersistentProperty;Ljava/util/Optional;)V",
"(Lorg/springframework/data/mapping/PersistentProperty<*>;Ljava/util/Optional<+Ljava/lang/Object;>)V", null);
"(Lorg/springframework/data/mapping/PersistentProperty;Ljava/lang/Object;)V",
"(Lorg/springframework/data/mapping/PersistentProperty<*>;Ljava/lang/Object;)V", null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
visitAssertNotNull(mv);
visitUnwrapValue(mv);
mv.visitVarInsn(ALOAD, 0);
@@ -908,8 +904,7 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
mv.visitLocalVariable(THIS_REF, referenceName(internalClassName), null, l0, l1, 0);
mv.visitLocalVariable("property", "Lorg/springframework/data/mapping/PersistentProperty;",
"Lorg/springframework/data/mapping/PersistentProperty<*>;", l0, l1, 1);
mv.visitLocalVariable("optional", referenceName(JAVA_UTIL_OPTIONAL), "Ljava/util/Optional<+Ljava/lang/Object;>;",
l0, l1, 2);
mv.visitLocalVariable("value", referenceName(JAVA_LANG_OBJECT), null, l0, l1, 2);
if (isAccessible(entity)) {
mv.visitLocalVariable(BEAN_FIELD, referenceName(entity.getType()), null, l0, l1, 3);
@@ -917,21 +912,10 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
mv.visitLocalVariable(BEAN_FIELD, referenceName(JAVA_LANG_OBJECT), null, l0, l1, 3);
}
mv.visitLocalVariable("value", referenceName(JAVA_LANG_OBJECT), null, l0, l1, 4);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
private static void visitUnwrapValue(MethodVisitor mv) {
mv.visitVarInsn(ALOAD, 2);
mv.visitInsn(ACONST_NULL);
mv.visitMethodInsn(INVOKEVIRTUAL, JAVA_UTIL_OPTIONAL, "orElse",
String.format("(%s)%s", referenceName(JAVA_LANG_OBJECT), referenceName(JAVA_LANG_OBJECT)), false);
mv.visitVarInsn(ASTORE, 4);
}
/**
* Generate the {@code switch(hashcode) {label: }} block.
*/
@@ -991,13 +975,13 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
mv.visitFieldInsn(GETSTATIC, internalClassName, setterName(property),
referenceName(JAVA_LANG_INVOKE_METHOD_HANDLE));
mv.visitVarInsn(ALOAD, 3);
mv.visitVarInsn(ALOAD, 4);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEVIRTUAL, JAVA_LANG_INVOKE_METHOD_HANDLE, "invoke",
String.format("(%s%s)V", referenceName(JAVA_LANG_OBJECT), referenceName(JAVA_LANG_OBJECT)), false);
} else {
// bean.set...(object)
mv.visitVarInsn(ALOAD, 3);
mv.visitVarInsn(ALOAD, 4);
mv.visitVarInsn(ALOAD, 2);
Class<?> parameterType = it.getParameterTypes()[0];
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(autoboxType(parameterType)));
@@ -1025,13 +1009,13 @@ public class ClassGeneratingPropertyAccessorFactory implements PersistentPropert
mv.visitFieldInsn(GETSTATIC, internalClassName, fieldSetterName(property),
referenceName(JAVA_LANG_INVOKE_METHOD_HANDLE));
mv.visitVarInsn(ALOAD, 3);
mv.visitVarInsn(ALOAD, 4);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEVIRTUAL, JAVA_LANG_INVOKE_METHOD_HANDLE, "invoke",
String.format("(%s%s)V", referenceName(JAVA_LANG_OBJECT), referenceName(JAVA_LANG_OBJECT)), false);
} else {
// bean.field
mv.visitVarInsn(ALOAD, 3);
mv.visitVarInsn(ALOAD, 4);
mv.visitVarInsn(ALOAD, 2);
Class<?> fieldType = it.getType();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-2017 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.
@@ -15,8 +15,6 @@
*/
package org.springframework.data.mapping.model;
import java.util.Optional;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PersistentPropertyAccessor;
@@ -27,8 +25,9 @@ import org.springframework.util.Assert;
* {@link #setProperty(PersistentProperty, Object)} to the type of the {@link PersistentProperty} using a
* {@link ConversionService}. Exposes {@link #getProperty(PersistentProperty, Class)} to allow obtaining the value of a
* property in a type the {@link ConversionService} can convert the raw type to.
*
*
* @author Oliver Gierke
* @author Mark Paluch
*/
public class ConvertingPropertyAccessor implements PersistentPropertyAccessor {
@@ -38,7 +37,7 @@ public class ConvertingPropertyAccessor implements PersistentPropertyAccessor {
/**
* Creates a new {@link ConvertingPropertyAccessor} for the given delegate {@link PersistentPropertyAccessor} and
* {@link ConversionService}.
*
*
* @param accessor must not be {@literal null}.
* @param conversionService must not be {@literal null}.
*/
@@ -51,32 +50,32 @@ public class ConvertingPropertyAccessor implements PersistentPropertyAccessor {
this.conversionService = conversionService;
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.PersistentPropertyAccessor#setProperty(org.springframework.data.mapping.PersistentProperty, java.lang.Object)
*/
@Override
public void setProperty(PersistentProperty<?> property, Optional<? extends Object> value) {
public void setProperty(PersistentProperty<?> property, Object value) {
accessor.setProperty(property, convertIfNecessary(value, property.getType()));
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.PersistentPropertyAccessor#getProperty(org.springframework.data.mapping.PersistentProperty)
*/
@Override
public Optional<Object> getProperty(PersistentProperty<?> property) {
public Object getProperty(PersistentProperty<?> property) {
return accessor.getProperty(property);
}
/**
* Returns the value of the given {@link PersistentProperty} converted to the given type.
*
*
* @param property must not be {@literal null}.
* @param targetType must not be {@literal null}.
* @return
*/
public <T> Optional<T> getProperty(PersistentProperty<?> property, Class<T> targetType) {
public <T> T getProperty(PersistentProperty<?> property, Class<T> targetType) {
Assert.notNull(property, "PersistentProperty must not be null!");
Assert.notNull(targetType, "Target type must not be null!");
@@ -84,7 +83,7 @@ public class ConvertingPropertyAccessor implements PersistentPropertyAccessor {
return convertIfNecessary(getProperty(property), targetType);
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.PersistentPropertyAccessor#getBean()
*/
@@ -96,13 +95,14 @@ public class ConvertingPropertyAccessor implements PersistentPropertyAccessor {
/**
* Triggers the conversion of the source value into the target type unless the value already is a value of given
* target type.
*
*
* @param source can be {@literal null}.
* @param type must not be {@literal null}.
* @return
*/
@SuppressWarnings("unchecked")
private <T> Optional<T> convertIfNecessary(Optional<? extends Object> source, Class<T> type) {
return source.map(it -> type.isAssignableFrom(it.getClass()) ? (T) it : conversionService.convert(it, type));
private <T> T convertIfNecessary(Object source, Class<T> type) {
return (T) (source == null ? null
: type.isAssignableFrom(source.getClass()) ? source : conversionService.convert(source, type));
}
}

View File

@@ -15,8 +15,6 @@
*/
package org.springframework.data.mapping.model;
import java.util.Optional;
import org.springframework.data.mapping.IdentifierAccessor;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
@@ -26,7 +24,7 @@ import org.springframework.util.Assert;
/**
* Default implementation of {@link IdentifierAccessor}.
*
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.10
@@ -39,7 +37,7 @@ public class IdPropertyIdentifierAccessor extends TargetAwareIdentifierAccessor
/**
* Creates a new {@link IdPropertyIdentifierAccessor} for the given {@link PersistentEntity} and
* {@link ConvertingPropertyAccessor}.
*
*
* @param entity must not be {@literal null}.
* @param target must not be {@literal null}.
*/
@@ -59,7 +57,7 @@ public class IdPropertyIdentifierAccessor extends TargetAwareIdentifierAccessor
* (non-Javadoc)
* @see org.springframework.data.keyvalue.core.IdentifierAccessor#getIdentifier()
*/
public Optional<Object> getIdentifier() {
public Object getIdentifier() {
return accessor.getProperty(idProperty);
}
}

View File

@@ -16,20 +16,21 @@
package org.springframework.data.mapping.model;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PreferredConstructor;
import org.springframework.util.ObjectUtils;
/**
* Exception being thrown in case an entity could not be instantiated in the process of a to-object-mapping.
*
*
* @author Oliver Gierke
* @author Jon Brisbin
* @author Christoph Strobl
* @author Mark Paluch
*/
public class MappingInstantiationException extends RuntimeException {
@@ -43,43 +44,58 @@ public class MappingInstantiationException extends RuntimeException {
/**
* Creates a new {@link MappingInstantiationException} for the given {@link PersistentEntity}, constructor arguments
* and the causing exception.
*
*
* @param entity
* @param arguments
* @param cause
*/
public MappingInstantiationException(Optional<PersistentEntity<?, ?>> entity, List<Object> arguments,
Exception cause) {
this(entity, arguments, null, cause);
public MappingInstantiationException(PersistentEntity<?, ?> entity, List<Object> arguments, Exception cause) {
this(Optional.ofNullable(entity), arguments, null, cause);
}
/**
* Creates a new {@link MappingInstantiationException} for the given constructor arguments and the causing exception.
*
* @param arguments
* @param cause
*/
public MappingInstantiationException(List<Object> arguments, Exception cause) {
this(Optional.empty(), arguments, null, cause);
}
private MappingInstantiationException(Optional<PersistentEntity<?, ?>> entity, List<Object> arguments, String message,
Exception cause) {
super(buildExceptionMessage(entity, arguments.stream(), message), cause);
super(buildExceptionMessage(entity, arguments, message), cause);
this.entityType = entity.map(PersistentEntity::getType).orElse(null);
this.constructor = entity.flatMap(PersistentEntity::getPersistenceConstructor).map(PreferredConstructor::getConstructor).orElse(null);
this.constructor = entity.flatMap(PersistentEntity::getPersistenceConstructor)
.map(PreferredConstructor::getConstructor).orElse(null);
this.constructorArguments = arguments;
}
private static String buildExceptionMessage(Optional<PersistentEntity<?, ?>> entity, Stream<Object> arguments,
String defaultMessage) {
private static String buildExceptionMessage(Optional<PersistentEntity<?, ?>> entity, List<Object> arguments,
String defaultMessage) {
return entity.map(it -> {
Optional<? extends PreferredConstructor<?, ?>> constructor = it.getPersistenceConstructor();
List<String> toStringArgs = new ArrayList<>(arguments.size());
for (Object o : arguments) {
toStringArgs.add(ObjectUtils.nullSafeToString(o));
}
return String.format(TEXT_TEMPLATE, it.getType().getName(),
constructor.map(c -> c.getConstructor().toString()).orElse("NO_CONSTRUCTOR"),
String.join(",", arguments.map(Object::toString).collect(Collectors.toList())));
constructor.map(c -> c.getConstructor().toString()).orElse("NO_CONSTRUCTOR"), //
String.join(",", toStringArgs));
}).orElse(defaultMessage);
}
/**
* Returns the type of the entity that was attempted to instantiate.
*
*
* @return the entityType
*/
public Optional<Class<?>> getEntityType() {
@@ -88,7 +104,7 @@ public class MappingInstantiationException extends RuntimeException {
/**
* The constructor used during the instantiation attempt.
*
*
* @return the constructor
*/
public Optional<Constructor<?>> getConstructor() {
@@ -97,7 +113,7 @@ public class MappingInstantiationException extends RuntimeException {
/**
* The constructor arguments used to invoke the constructor.
*
*
* @return the constructorArguments
*/
public List<Object> getConstructorArguments() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2012 by the original author(s).
* Copyright (c) 2011-2017 by the original author(s).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,23 +15,21 @@
*/
package org.springframework.data.mapping.model;
import java.util.Optional;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PreferredConstructor.Parameter;
/**
* Callback interface to lookup values for a given {@link Parameter}.
*
*
* @author Oliver Gierke
*/
public interface ParameterValueProvider<P extends PersistentProperty<P>> {
/**
* Returns the value to be used for the given {@link Parameter} (usually when entity instances are created).
*
*
* @param parameter must not be {@literal null}.
* @return
*/
<T> Optional<T> getParameterValue(Parameter<T, P> parameter);
<T> T getParameterValue(Parameter<T, P> parameter);
}

View File

@@ -15,8 +15,6 @@
*/
package org.springframework.data.mapping.model;
import java.util.Optional;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PreferredConstructor;
@@ -28,31 +26,29 @@ import org.springframework.util.Assert;
* the value of the property referenced by the given {@link Parameter}. Additionally a
* {@link DefaultSpELExpressionEvaluator} can be configured to get property value resolution trumped by a SpEL
* expression evaluation.
*
*
* @author Oliver Gierke
* @author Christoph Strobl
*/
public class PersistentEntityParameterValueProvider<P extends PersistentProperty<P>>
implements ParameterValueProvider<P> {
private final PersistentEntity<?, P> entity;
private final PropertyValueProvider<P> provider;
private final Optional<Object> parent;
private final Object parent;
/**
* Creates a new {@link PersistentEntityParameterValueProvider} for the given {@link PersistentEntity} and
* {@link PropertyValueProvider}.
*
*
* @param entity must not be {@literal null}.
* @param provider must not be {@literal null}.
* @param parent the parent object being created currently, can be {@literal null}.
*/
public PersistentEntityParameterValueProvider(PersistentEntity<?, P> entity, PropertyValueProvider<P> provider,
Optional<Object> parent) {
Object parent) {
Assert.notNull(entity, "Entity must not be null!");
Assert.notNull(provider, "Provider must not be null!");
Assert.notNull(parent, "Parent must not be null!");
this.entity = entity;
this.provider = provider;
@@ -64,18 +60,21 @@ public class PersistentEntityParameterValueProvider<P extends PersistentProperty
* @see org.springframework.data.mapping.model.ParameterValueProvider#getParameterValue(org.springframework.data.mapping.PreferredConstructor.Parameter)
*/
@SuppressWarnings("unchecked")
public <T> Optional<T> getParameterValue(Parameter<T, P> parameter) {
public <T> T getParameterValue(Parameter<T, P> parameter) {
PreferredConstructor<?, P> constructor = entity.getPersistenceConstructor().get();
PreferredConstructor<?, P> constructor = entity.getPersistenceConstructor().orElse(null);
if (constructor.isEnclosingClassParameter(parameter)) {
return (Optional<T>) parent;
return (T) parent;
}
return provider.getPropertyValue(parameter.getName()//
.flatMap(entity::getPersistentProperty)//
.orElseThrow(() -> new MappingException(
String.format("No property %s found on entity %s to bind constructor parameter to!", parameter.getName(),
entity.getType()))));
P property = entity.getPersistentProperty(parameter.getName().orElse(null)).orElse(null);
if (property == null) {
throw new MappingException(String.format("No property %s found on entity %s to bind constructor parameter to!",
parameter.getName(), entity.getType()));
}
return provider.getPropertyValue(property);
}
}

View File

@@ -28,31 +28,40 @@ import org.springframework.util.Assert;
/**
* Value object to abstract the concept of a property backed by a {@link Field} and / or a {@link PropertyDescriptor}.
*
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Mark Paluch
*/
public class Property {
private final @Getter Optional<Field> field;
private final Optional<PropertyDescriptor> descriptor;
private final Lazy<Class<?>> rawType;
private final Class<?> rawType;
private final Lazy<Integer> hashCode;
private final Optional<Method> getter;
private final Optional<Method> setter;
private Property(Optional<Field> field, Optional<PropertyDescriptor> descriptor) {
this.field = field;
this.descriptor = descriptor;
this.hashCode = Lazy.of(this::computeHashCode);
this.rawType = Lazy.of(
() -> field.<Class<?>> map(Field::getType).orElseGet(() -> descriptor.map(PropertyDescriptor::getPropertyType)//
.orElseThrow(IllegalStateException::new)));
this.rawType = field.<Class<?>> map(Field::getType)
.orElseGet(() -> descriptor.map(PropertyDescriptor::getPropertyType)//
.orElse(null));
this.getter = descriptor.map(PropertyDescriptor::getReadMethod)//
.filter(it -> getType() != null).filter(it -> getType().isAssignableFrom(it.getReturnType()));
this.setter = descriptor.map(PropertyDescriptor::getWriteMethod)//
.filter(it -> getType() != null).filter(it -> it.getParameterTypes()[0].isAssignableFrom(getType()));
}
/**
* Creates a new {@link Property} backed by the given field.
*
*
* @param field must not be {@literal null}.
* @return
*/
@@ -65,7 +74,7 @@ public class Property {
/**
* Creates a new {@link Property} backed by the given {@link Field} and {@link PropertyDescriptor}.
*
*
* @param field must not be {@literal null}.
* @param descriptor must not be {@literal null}.
* @return
@@ -80,7 +89,7 @@ public class Property {
/**
* Creates a new {@link Property} for the given {@link PropertyDescriptor}.
*
*
* @param descriptor must not be {@literal null}.
* @return
*/
@@ -93,7 +102,7 @@ public class Property {
/**
* Returns whether the property is backed by a field.
*
*
* @return
*/
public boolean isFieldBacked() {
@@ -102,27 +111,25 @@ public class Property {
/**
* Returns the getter of the property if available and if it matches the type of the property.
*
*
* @return will never be {@literal null}.
*/
public Optional<Method> getGetter() {
return descriptor.map(PropertyDescriptor::getReadMethod)//
.filter(it -> getType().isAssignableFrom(it.getReturnType()));
return getter;
}
/**
* Returns the setter of the property if available and if its first (only) parameter matches the type of the property.
*
*
* @return will never be {@literal null}.
*/
public Optional<Method> getSetter() {
return descriptor.map(PropertyDescriptor::getWriteMethod)//
.filter(it -> it.getParameterTypes()[0].isAssignableFrom(getType()));
return setter;
}
/**
* Returns whether the property exposes a getter or a setter.
*
*
* @return
*/
public boolean hasAccessor() {
@@ -131,7 +138,7 @@ public class Property {
/**
* Returns the name of the property.
*
*
* @return will never be {@literal null}.
*/
public String getName() {
@@ -143,11 +150,11 @@ public class Property {
/**
* Returns the type of the property.
*
*
* @return will never be {@literal null}.
*/
public Class<?> getType() {
return rawType.get();
return rawType;
}
private int computeHashCode() {
@@ -156,7 +163,7 @@ public class Property {
.orElseGet(() -> this.descriptor.map(PropertyDescriptor::hashCode).orElseThrow(IllegalStateException::new));
}
/*
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@@ -165,7 +172,7 @@ public class Property {
return hashCode.get();
}
/*
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@@ -185,7 +192,7 @@ public class Property {
return this.field.isPresent() ? this.field.equals(that.field) : this.descriptor.equals(that.descriptor);
}
/*
/*
* (non-Javadoc)
* @see java.lang.Object#toString()
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012 the original author or authors.
* Copyright 2012-2017 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.
@@ -15,22 +15,20 @@
*/
package org.springframework.data.mapping.model;
import java.util.Optional;
import org.springframework.data.mapping.PersistentProperty;
/**
* SPI for components to provide values for as {@link PersistentProperty}.
*
*
* @author Oliver Gierke
*/
public interface PropertyValueProvider<P extends PersistentProperty<P>> {
/**
* Returns a value for the given {@link PersistentProperty}.
*
*
* @param property will never be {@literal null}.
* @return
*/
<T> Optional<T> getPropertyValue(P property);
<T> T getPropertyValue(P property);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012 the original author or authors.
* Copyright 2012-2017 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.
@@ -15,8 +15,6 @@
*/
package org.springframework.data.mapping.model;
import java.util.Optional;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PreferredConstructor.Parameter;
@@ -25,8 +23,9 @@ import org.springframework.util.Assert;
/**
* {@link ParameterValueProvider} that can be used to front a {@link ParameterValueProvider} delegate to prefer a Spel
* expression evaluation over directly resolving the parameter value with the delegate.
*
*
* @author Oliver Gierke
* @author Mark Paluch
*/
public class SpELExpressionParameterValueProvider<P extends PersistentProperty<P>>
implements ParameterValueProvider<P> {
@@ -39,7 +38,7 @@ public class SpELExpressionParameterValueProvider<P extends PersistentProperty<P
* Creates a new {@link SpELExpressionParameterValueProvider} using the given {@link SpELExpressionEvaluator},
* {@link ConversionService} and {@link ParameterValueProvider} delegate to forward calls to, that resolve parameters
* that do not have a Spel expression configured with them.
*
*
* @param evaluator must not be {@literal null}.
* @param conversionService must not be {@literal null}.
* @param delegate must not be {@literal null}.
@@ -56,22 +55,24 @@ public class SpELExpressionParameterValueProvider<P extends PersistentProperty<P
this.delegate = delegate;
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.model.ParameterValueProvider#getParameterValue(org.springframework.data.mapping.PreferredConstructor.Parameter)
*/
public <T> Optional<T> getParameterValue(Parameter<T, P> parameter) {
public <T> T getParameterValue(Parameter<T, P> parameter) {
return parameter.getSpelExpression()//
.map(it -> Optional.ofNullable(evaluator.evaluate(it))//
.map(result -> potentiallyConvertSpelValue(result, parameter)))
.orElseGet(() -> delegate.getParameterValue(parameter));
if (!parameter.hasSpelExpression()) {
return delegate == null ? null : delegate.getParameterValue(parameter);
}
Object object = evaluator.evaluate(parameter.getSpelExpression().orElse(null));
return object == null ? null : potentiallyConvertSpelValue(object, parameter);
}
/**
* Hook to allow to massage the value resulting from the Spel expression evaluation. Default implementation will
* leverage the configured {@link ConversionService} to massage the value into the parameter type.
*
*
* @param object the value to massage, will never be {@literal null}.
* @param parameter the {@link Parameter} we create the value for
* @return

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011 the original author or authors.
* Copyright 2011-2017 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.
@@ -15,36 +15,35 @@
*/
package org.springframework.data.repository.core;
import java.util.Optional;
import org.springframework.util.Assert;
/**
* Extension of {@link EntityMetadata} to add functionality to query information of entity instances.
*
*
* @author Oliver Gierke
* @author Mark Paluch
*/
public interface EntityInformation<T, ID> extends EntityMetadata<T> {
/**
* Returns whether the given entity is considered to be new.
*
*
* @param entity must never be {@literal null}
* @return
*/
boolean isNew(T entity);
/**
* Returns the id of the given entity or {@link Optional#empty()} if none can be obtained.
*
* Returns the id of the given entity or {@literal null} if none can be obtained.
*
* @param entity must never be {@literal null}
* @return
*/
Optional<ID> getId(T entity);
ID getId(T entity);
/**
* Returns the identifier of the given entity.
*
*
* @param entity must not be {@literal null}.
* @return the identifier of the given entity
* @throws IllegalArgumentException in case no id could be obtained from the given entity
@@ -54,13 +53,18 @@ public interface EntityInformation<T, ID> extends EntityMetadata<T> {
Assert.notNull(entity, "Entity must not be null!");
return getId(entity).orElseThrow(() -> new IllegalArgumentException(
String.format("Could not obtain required identifier from entity %s!", entity)));
ID id = getId(entity);
if (id != null) {
return id;
}
throw new IllegalArgumentException(String.format("Could not obtain required identifier from entity %s!", entity));
}
/**
* Returns the type of the id of the entity.
*
*
* @return
*/
Class<ID> getIdType();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 the original author or authors.
* Copyright 2011-2017 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.
@@ -18,16 +18,15 @@ package org.springframework.data.repository.core.support;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import java.util.Optional;
import org.springframework.data.repository.core.EntityInformation;
/**
* Base class for implementations of {@link EntityInformation}. Considers an entity to be new whenever
* {@link #getId(Object)} returns {@literal null}.
*
*
* @author Oliver Gierke
* @author Nick Williams
* @author Mark Paluch
*/
@RequiredArgsConstructor
public abstract class AbstractEntityInformation<T, ID> implements EntityInformation<T, ID> {
@@ -40,22 +39,18 @@ public abstract class AbstractEntityInformation<T, ID> implements EntityInformat
*/
public boolean isNew(T entity) {
Optional<ID> id = getId(entity);
ID id = getId(entity);
Class<ID> idType = getIdType();
if (!idType.isPrimitive()) {
return !id.isPresent();
return id == null;
}
return id.map(it -> {
if (id instanceof Number) {
return ((Number) id).longValue() == 0L;
}
if (it instanceof Number) {
return ((Number) it).longValue() == 0L;
}
return null;
}).orElseThrow(() -> new IllegalArgumentException(String.format("Unsupported primitive id type %s!", idType)));
throw new IllegalArgumentException(String.format("Unsupported primitive id type %s!", idType));
}
/*

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012 the original author or authors.
* Copyright 2012-2017 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.
@@ -18,14 +18,12 @@ package org.springframework.data.repository.core.support;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import java.util.Optional;
import org.springframework.data.repository.core.EntityInformation;
/**
* Useful base class to implement custom {@link EntityInformation}s and delegate execution of standard methods from
* {@link EntityInformation} to a special implementation.
*
*
* @author Oliver Gierke
*/
@RequiredArgsConstructor
@@ -33,7 +31,7 @@ public class DelegatingEntityInformation<T, ID> implements EntityInformation<T,
private final @NonNull EntityInformation<T, ID> delegate;
/*
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.EntityMetadata#getJavaType()
*/
@@ -41,7 +39,7 @@ public class DelegatingEntityInformation<T, ID> implements EntityInformation<T,
return delegate.getJavaType();
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.EntityInformation#isNew(java.lang.Object)
*/
@@ -49,15 +47,15 @@ public class DelegatingEntityInformation<T, ID> implements EntityInformation<T,
return delegate.isNew(entity);
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.EntityInformation#getId(java.lang.Object)
*/
public Optional<ID> getId(T entity) {
public ID getId(T entity) {
return delegate.getId(entity);
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.EntityInformation#getIdType()
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2008-201 the original author or authors.
* Copyright 2008-2017 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.
@@ -15,8 +15,6 @@
*/
package org.springframework.data.repository.core.support;
import java.util.Optional;
import org.springframework.core.ResolvableType;
import org.springframework.data.domain.Persistable;
import org.springframework.data.repository.core.EntityMetadata;
@@ -24,7 +22,7 @@ import org.springframework.data.repository.core.EntityMetadata;
/**
* Implementation of {@link EntityMetadata} that assumes the entity handled implements {@link Persistable} and uses
* {@link Persistable#isNew()} for the {@link #isNew(Object)} check.
*
*
* @author Oliver Gierke
*/
public class PersistableEntityInformation<T extends Persistable<ID>, ID> extends AbstractEntityInformation<T, ID> {
@@ -33,7 +31,7 @@ public class PersistableEntityInformation<T extends Persistable<ID>, ID> extends
/**
* Creates a new {@link PersistableEntityInformation}.
*
*
* @param domainClass
*/
@SuppressWarnings("unchecked")
@@ -57,8 +55,8 @@ public class PersistableEntityInformation<T extends Persistable<ID>, ID> extends
* @see org.springframework.data.repository.core.EntityInformation#getId(java.lang.Object)
*/
@Override
public Optional<ID> getId(T entity) {
return Optional.ofNullable(entity.getId());
public ID getId(T entity) {
return entity.getId();
}
/*

View File

@@ -15,8 +15,6 @@
*/
package org.springframework.data.repository.core.support;
import java.util.Optional;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.repository.core.EntityInformation;
@@ -24,7 +22,7 @@ import org.springframework.data.repository.core.EntityInformation;
/**
* {@link EntityInformation} implementation that uses a {@link PersistentEntity} to obtain id type information and uses
* a {@link org.springframework.data.mapping.IdentifierAccessor} to access the property value if requested.
*
*
* @author Oliver Gierke
* @author Christoph Strobl
*/
@@ -35,7 +33,7 @@ public class PersistentEntityInformation<T, ID> extends AbstractEntityInformatio
/**
* Creates a new {@link PersistableEntityInformation} for the given {@link PersistentEntity}.
*
*
* @param entity must not be {@literal null}.
*/
public PersistentEntityInformation(PersistentEntity<T, ?> entity) {
@@ -44,16 +42,16 @@ public class PersistentEntityInformation<T, ID> extends AbstractEntityInformatio
this.persistentEntity = entity;
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.EntityInformation#getId(java.lang.Object)
*/
@Override
public Optional<ID> getId(T entity) {
return persistentEntity.getIdentifierAccessor(entity).getIdentifier().map(it -> (ID) it);
public ID getId(T entity) {
return (ID) persistentEntity.getIdentifierAccessor(entity).getIdentifier();
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.EntityInformation#getIdType()
*/

View File

@@ -17,7 +17,6 @@ package org.springframework.data.repository.core.support;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Optional;
import org.springframework.data.annotation.Id;
import org.springframework.data.repository.core.EntityInformation;
@@ -27,7 +26,7 @@ import org.springframework.util.ReflectionUtils;
/**
* {@link EntityInformation} implementation that inspects fields for an annotation and looks up this field's value to
* retrieve the id.
*
*
* @author Oliver Gierke
* @author Christoph Strobl
*/
@@ -40,7 +39,7 @@ public class ReflectionEntityInformation<T, ID> extends AbstractEntityInformatio
/**
* Creates a new {@link ReflectionEntityInformation} inspecting the given domain class for a field carrying the
* {@link Id} annotation.
*
*
* @param domainClass must not be {@literal null}.
*/
public ReflectionEntityInformation(Class<T> domainClass) {
@@ -50,7 +49,7 @@ public class ReflectionEntityInformation<T, ID> extends AbstractEntityInformatio
/**
* Creates a new {@link ReflectionEntityInformation} inspecting the given domain class for a field carrying the given
* annotation.
*
*
* @param domainClass must not be {@literal null}.
* @param annotation must not be {@literal null}.
*/
@@ -70,16 +69,16 @@ public class ReflectionEntityInformation<T, ID> extends AbstractEntityInformatio
ReflectionUtils.makeAccessible(field);
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.EntityInformation#getId(java.lang.Object)
*/
@SuppressWarnings("unchecked")
public Optional<ID> getId(Object entity) {
return entity == null ? null : Optional.ofNullable((ID) ReflectionUtils.getField(field, entity));
public ID getId(Object entity) {
return entity == null ? null : (ID) ReflectionUtils.getField(field, entity);
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.EntityInformation#getIdType()
*/