Introduce caching for commonly used model computations.
We now cache the outcome for column types, AnnotatedType lookuop by annotation and bypass the conversion service by considering primitive type wrappers in the assignability check. Closes #1218
This commit is contained in:
@@ -22,6 +22,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
@@ -76,6 +77,8 @@ class DefaultColumnTypeResolver implements ColumnTypeResolver {
|
||||
private final UserTypeResolver userTypeResolver;
|
||||
private final Supplier<CodecRegistry> codecRegistry;
|
||||
private final Supplier<CustomConversions> customConversions;
|
||||
private final Map<CassandraPersistentProperty, CassandraColumnType> columnTypeCache = new ConcurrentHashMap<>();
|
||||
private final Map<TypeInformation<?>, CassandraColumnType> typeInformationColumnTypeCache = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultColumnTypeResolver}.
|
||||
@@ -100,6 +103,18 @@ class DefaultColumnTypeResolver implements ColumnTypeResolver {
|
||||
|
||||
Assert.notNull(property, "Property must not be null");
|
||||
|
||||
CassandraColumnType cassandraColumnType = columnTypeCache.get(property);
|
||||
if (cassandraColumnType == null) {
|
||||
// avoid recursive update
|
||||
cassandraColumnType = doResolve(property);
|
||||
columnTypeCache.put(property, cassandraColumnType);
|
||||
}
|
||||
|
||||
return cassandraColumnType;
|
||||
}
|
||||
|
||||
private CassandraColumnType doResolve(CassandraPersistentProperty property) {
|
||||
|
||||
if (property.isAnnotationPresent(CassandraType.class)) {
|
||||
|
||||
CassandraType annotation = property.getRequiredAnnotation(CassandraType.class);
|
||||
@@ -165,7 +180,17 @@ class DefaultColumnTypeResolver implements ColumnTypeResolver {
|
||||
|
||||
@Override
|
||||
public CassandraColumnType resolve(TypeInformation<?> typeInformation) {
|
||||
return resolve(typeInformation, FrozenIndicator.NOT_FROZEN);
|
||||
|
||||
Assert.notNull(typeInformation, "TypeInformation must not be null");
|
||||
|
||||
CassandraColumnType cassandraColumnType = typeInformationColumnTypeCache.get(typeInformation);
|
||||
if (cassandraColumnType == null) {
|
||||
// avoid recursive update
|
||||
cassandraColumnType = resolve(typeInformation, FrozenIndicator.NOT_FROZEN);
|
||||
typeInformationColumnTypeCache.put(typeInformation, cassandraColumnType);
|
||||
}
|
||||
|
||||
return cassandraColumnType;
|
||||
}
|
||||
|
||||
private CassandraColumnType resolve(TypeInformation<?> typeInformation, FrozenIndicator frozen) {
|
||||
|
||||
@@ -1031,7 +1031,8 @@ public class MappingCassandraConverter extends AbstractCassandraConverter
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private Object getPotentiallyConvertedSimpleRead(Object value, @Nullable Class<?> target) {
|
||||
|
||||
if (value == null || target == null || target.isAssignableFrom(value.getClass())) {
|
||||
if (value == null || target == null
|
||||
|| ClassUtils.resolvePrimitiveIfNecessary(target).isAssignableFrom(value.getClass())) {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,9 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP
|
||||
this.columnName = determineColumnName();
|
||||
}
|
||||
|
||||
Assert.state(this.columnName != null, () -> String.format("Cannot determine column name for %s", this));
|
||||
if (columnName == null) {
|
||||
throw new IllegalStateException(String.format("Cannot determine column name for %s", this));
|
||||
}
|
||||
|
||||
return this.columnName;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.core.mapping;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.data.cassandra.core.cql.Ordering;
|
||||
import org.springframework.data.mapping.model.Property;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
@@ -36,6 +42,7 @@ public class CachingCassandraPersistentProperty extends BasicCassandraPersistent
|
||||
private final boolean isPrimaryKeyColumn;
|
||||
private final boolean isEmbedded;
|
||||
private final boolean isStaticColumn;
|
||||
private final Map<Class<? extends Annotation>, Optional<AnnotatedType>> findAnnotatedTypeCache = new ConcurrentHashMap<>();
|
||||
|
||||
public CachingCassandraPersistentProperty(Property property, CassandraPersistentEntity<?> owner,
|
||||
SimpleTypeHolder simpleTypeHolder) {
|
||||
@@ -85,4 +92,10 @@ public class CachingCassandraPersistentProperty extends BasicCassandraPersistent
|
||||
public boolean isEmbedded() {
|
||||
return isEmbedded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotatedType findAnnotatedType(Class<? extends Annotation> annotationType) {
|
||||
return findAnnotatedTypeCache
|
||||
.computeIfAbsent(annotationType, key -> Optional.ofNullable(super.findAnnotatedType(key))).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user