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:
committed by
Oliver Gierke
parent
4aa083377b
commit
74fbe13f54
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
*/
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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()
|
||||
*/
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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()
|
||||
*/
|
||||
|
||||
@@ -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()
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user