DATAJDBC-399 - Performance improvements in metadata lookups.
Avoid Stream usage in favor of a simple for loop in event triggering in JdbcAggregateTemplate. Tweaked JdbcMappingContext to verify the presence of parameter names on metadata creation. Avoid the re-resolution of the column name for a property by caching the resolved column name. This significantly improves performance as it avoids repeated parsing and concatenation of strings. Added caching to PersistentPropertyPathExtension.
This commit is contained in:
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
package org.springframework.data.jdbc.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
@@ -364,13 +364,17 @@ public class JdbcAggregateTemplate implements JdbcAggregateOperations {
|
||||
|
||||
private <T> Iterable<T> triggerAfterLoad(Iterable<T> all) {
|
||||
|
||||
return StreamSupport.stream(all.spliterator(), false).map(e -> {
|
||||
List<T> result = new ArrayList<>();
|
||||
|
||||
for (T e : all) {
|
||||
|
||||
RelationalPersistentEntity<?> entity = context.getRequiredPersistentEntity(e.getClass());
|
||||
IdentifierAccessor identifierAccessor = entity.getIdentifierAccessor(e);
|
||||
|
||||
return triggerAfterLoad(identifierAccessor.getRequiredIdentifier(), e);
|
||||
}).collect(Collectors.toList());
|
||||
result.add(triggerAfterLoad(identifierAccessor.getRequiredIdentifier(), e));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private <T> T triggerAfterLoad(Object id, T entity) {
|
||||
|
||||
@@ -18,9 +18,9 @@ package org.springframework.data.jdbc.core.convert;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
|
||||
import org.springframework.util.ConcurrentReferenceHashMap;
|
||||
|
||||
/**
|
||||
* Provides {@link SqlGenerator}s per domain type. Instances get cached, so when asked multiple times for the same
|
||||
@@ -31,12 +31,10 @@ import org.springframework.data.relational.core.mapping.RelationalMappingContext
|
||||
@RequiredArgsConstructor
|
||||
public class SqlGeneratorSource {
|
||||
|
||||
private final Map<Class, SqlGenerator> sqlGeneratorCache = new ConcurrentHashMap<>();
|
||||
private final Map<Class<?>, SqlGenerator> CACHE = new ConcurrentReferenceHashMap<>();
|
||||
private final RelationalMappingContext context;
|
||||
|
||||
SqlGenerator getSqlGenerator(Class<?> domainType) {
|
||||
|
||||
return sqlGeneratorCache.computeIfAbsent(domainType,
|
||||
t -> new SqlGenerator(context, context.getRequiredPersistentEntity(t)));
|
||||
return CACHE.computeIfAbsent(domainType, t -> new SqlGenerator(context, context.getRequiredPersistentEntity(t)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.jdbc.core.mapping;
|
||||
|
||||
import org.springframework.data.mapping.PreferredConstructor;
|
||||
import org.springframework.data.mapping.PreferredConstructor.Parameter;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.Property;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
@@ -23,6 +25,8 @@ import org.springframework.data.relational.core.mapping.RelationalMappingContext
|
||||
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
|
||||
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link MappingContext} implementation for JDBC.
|
||||
@@ -35,6 +39,8 @@ import org.springframework.data.util.TypeInformation;
|
||||
*/
|
||||
public class JdbcMappingContext extends RelationalMappingContext {
|
||||
|
||||
private static final String MISSING_PARAMETER_NAME = "A constructor parameter name must not be null to be used with Spring Data JDBC! Offending parameter: %s";
|
||||
|
||||
/**
|
||||
* Creates a new {@link JdbcMappingContext}.
|
||||
*/
|
||||
@@ -51,6 +57,27 @@ public class JdbcMappingContext extends RelationalMappingContext {
|
||||
super(namingStrategy);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.relational.core.mapping.RelationalMappingContext#createPersistentEntity(org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
@Override
|
||||
protected <T> RelationalPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
|
||||
RelationalPersistentEntity<T> entity = super.createPersistentEntity(typeInformation);
|
||||
PreferredConstructor<T, RelationalPersistentProperty> constructor = entity.getPersistenceConstructor();
|
||||
|
||||
if (constructor == null) {
|
||||
return entity;
|
||||
}
|
||||
|
||||
for (Parameter<Object, RelationalPersistentProperty> parameter : constructor.getParameters()) {
|
||||
Assert.state(StringUtils.hasText(parameter.getName()), () -> String.format(MISSING_PARAMETER_NAME, parameter));
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentProperty(org.springframework.data.mapping.model.Property, org.springframework.data.mapping.model.MutablePersistentEntity, org.springframework.data.mapping.model.SimpleTypeHolder)
|
||||
|
||||
@@ -20,7 +20,6 @@ import static org.assertj.core.api.Assertions.*;
|
||||
import org.assertj.core.api.SoftAssertions;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.jdbc.core.convert.SqlGenerator;
|
||||
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
|
||||
import org.springframework.data.jdbc.core.mapping.PersistentPropertyPathTestUtils;
|
||||
import org.springframework.data.mapping.PersistentPropertyPath;
|
||||
|
||||
Reference in New Issue
Block a user