Adapt to changes in entity creation metadata APIs in Spring Data Commons.

This commit is contained in:
Oliver Drotbohm
2022-02-15 15:41:27 +01:00
parent 3f02e39d89
commit 43e482e6a7
5 changed files with 15 additions and 123 deletions

View File

@@ -27,7 +27,6 @@ import java.util.function.Predicate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.context.ApplicationContext;
@@ -40,15 +39,7 @@ import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.cassandra.core.mapping.*;
import org.springframework.data.cassandra.core.mapping.Embedded.OnEmpty;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.mapping.AccessOptions;
import org.springframework.data.mapping.MappingException;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.mapping.PersistentPropertyPathAccessor;
import org.springframework.data.mapping.PreferredConstructor;
import org.springframework.data.mapping.PreferredConstructor.Parameter;
import org.springframework.data.mapping.*;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator;
@@ -1406,10 +1397,9 @@ public class MappingCassandraConverter extends AbstractCassandraConverter
@SuppressWarnings("unchecked")
public <T> T getParameterValue(Parameter<T, CassandraPersistentProperty> parameter) {
PreferredConstructor<CassandraPersistentEntity<?>, CassandraPersistentProperty> constructor = (PreferredConstructor<CassandraPersistentEntity<?>, CassandraPersistentProperty>) entity
.getPersistenceConstructor();
InstanceCreatorMetadata<CassandraPersistentProperty> creatorMetadata = entity.getInstanceCreatorMetadata();
if (constructor != null && constructor.isEnclosingClassParameter(parameter)) {
if (creatorMetadata != null && creatorMetadata.isParentParameter(parameter)) {
return (T) parent;
}

View File

@@ -132,11 +132,21 @@ public class EmbeddedEntityOperations {
public PreferredConstructor<T, CassandraPersistentProperty> getPersistenceConstructor() {
return delegate.getPersistenceConstructor();
}
@Override
public InstanceCreatorMetadata<CassandraPersistentProperty> getInstanceCreatorMetadata() {
return delegate.getInstanceCreatorMetadata();
}
@Override
public boolean isConstructorArgument(PersistentProperty<?> property) {
return delegate.isConstructorArgument(property);
}
@Override
public boolean isCreatorArgument(PersistentProperty<?> property) {
return delegate.isCreatorArgument(property);
}
@Override
public boolean isIdProperty(PersistentProperty<?> property) {

View File

@@ -23,6 +23,7 @@ import org.springframework.data.cassandra.core.CassandraOperations;
import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity;
import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty;
import org.springframework.data.cassandra.core.query.CassandraPageRequest;
import org.springframework.data.convert.DtoInstantiatingConverter;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;

View File

@@ -1,109 +0,0 @@
/*
* Copyright 2016-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.cassandra.repository.query;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity;
import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty;
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.PreferredConstructor.Parameter;
import org.springframework.data.mapping.SimplePropertyHandler;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.EntityInstantiator;
import org.springframework.data.mapping.model.EntityInstantiators;
import org.springframework.data.mapping.model.ParameterValueProvider;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* {@link Converter} to instantiate DTOs from fully equipped domain objects.
*
* @author Mark Paluch
*/
class DtoInstantiatingConverter implements Converter<Object, Object> {
private final Class<?> targetType;
private final MappingContext<? extends PersistentEntity<?, ?>, ? extends PersistentProperty<?>> context;
private final EntityInstantiator instantiator;
/**
* Create a new {@link Converter} to instantiate DTOs.
*
* @param dtoType must not be {@literal null}.
* @param context must not be {@literal null}.
* @param instantiators must not be {@literal null}.
*/
DtoInstantiatingConverter(Class<?> dtoType,
MappingContext<? extends CassandraPersistentEntity<?>, CassandraPersistentProperty> context,
EntityInstantiators instantiator) {
Assert.notNull(dtoType, "DTO type must not be null!");
Assert.notNull(context, "MappingContext must not be null!");
Assert.notNull(instantiator, "EntityInstantiators must not be null!");
this.targetType = dtoType;
this.context = context;
this.instantiator = instantiator.getInstantiatorFor(context.getRequiredPersistentEntity(dtoType));
}
@Override
public Object convert(Object source) {
if (targetType.isInterface()) {
return source;
}
PersistentEntity<?, ?> sourceEntity = context.getRequiredPersistentEntity(source.getClass());
PersistentPropertyAccessor sourceAccessor = sourceEntity.getPropertyAccessor(source);
PersistentEntity<?, ?> targetEntity = context.getRequiredPersistentEntity(targetType);
@SuppressWarnings({ "rawtypes", "unchecked" })
Object dto = instantiator.createInstance(targetEntity, new ParameterValueProvider() {
@Override
@Nullable
public Object getParameterValue(Parameter parameter) {
if (parameter.getName() == null) {
throw new IllegalArgumentException(String.format("Parameter %s does not have a name", parameter));
}
return sourceAccessor.getProperty(sourceEntity.getRequiredPersistentProperty(parameter.getName()));
}
});
final PersistentPropertyAccessor targetAccessor = targetEntity.getPropertyAccessor(dto);
PreferredConstructor<?, ? extends PersistentProperty<?>> constructor = targetEntity.getPersistenceConstructor();
targetEntity.doWithProperties((SimplePropertyHandler) property -> {
if (constructor != null && !constructor.isConstructorParameter(property)) {
return;
}
targetAccessor.setProperty(property,
sourceAccessor.getProperty(sourceEntity.getRequiredPersistentProperty(property.getName())));
});
return dto;
}
}

View File

@@ -21,13 +21,13 @@ import reactor.core.publisher.Mono;
import java.util.List;
import org.reactivestreams.Publisher;
import org.springframework.core.convert.converter.Converter;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.data.cassandra.core.ReactiveCassandraOperations;
import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity;
import org.springframework.data.cassandra.core.mapping.CassandraPersistentProperty;
import org.springframework.data.cassandra.core.query.CassandraPageRequest;
import org.springframework.data.convert.DtoInstantiatingConverter;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;