Introduce AggregatePath.

AggregatePath replaces PersistentPropertyPathExtension.
It gets created and cached by the RelationalMappingContext, which should be more efficient and certainly looks nicer.

Closes #1525
Original pull request #1486
This commit is contained in:
Jens Schauder
2023-05-17 14:43:12 +02:00
parent 7d5bc1cbd9
commit d00e928db5
44 changed files with 1786 additions and 291 deletions

View File

@@ -15,16 +15,7 @@
*/
package org.springframework.data.jdbc.core;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
@@ -38,11 +29,12 @@ import org.springframework.data.jdbc.core.convert.JdbcIdentifierBuilder;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.mapping.PersistentPropertyPathAccessor;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.relational.core.conversion.DbAction;
import org.springframework.data.relational.core.conversion.DbActionExecutionResult;
import org.springframework.data.relational.core.conversion.IdValueSource;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
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.relational.core.sql.LockMode;
@@ -65,7 +57,7 @@ class JdbcAggregateChangeExecutionContext {
private static final String UPDATE_FAILED = "Failed to update entity [%s]; Id [%s] not found in database";
private static final String UPDATE_FAILED_OPTIMISTIC_LOCKING = "Failed to update entity [%s]; The entity was updated since it was rea or it isn't in the database at all";
private final MappingContext<? extends RelationalPersistentEntity<?>, ? extends RelationalPersistentProperty> context;
private final RelationalMappingContext context;
private final JdbcConverter converter;
private final DataAccessStrategy accessStrategy;
@@ -184,12 +176,11 @@ class JdbcAggregateChangeExecutionContext {
Object id = getParentId(action);
JdbcIdentifierBuilder identifier = JdbcIdentifierBuilder //
.forBackReferences(converter, new PersistentPropertyPathExtension(context, action.getPropertyPath()), id);
.forBackReferences(converter, context.getAggregatePath(action.getPropertyPath()), id);
for (Map.Entry<PersistentPropertyPath<RelationalPersistentProperty>, Object> qualifier : action.getQualifiers()
.entrySet()) {
identifier = identifier.withQualifier(new PersistentPropertyPathExtension(context, qualifier.getKey()),
qualifier.getValue());
identifier = identifier.withQualifier(context.getAggregatePath(qualifier.getKey()), qualifier.getValue());
}
return identifier.build();
@@ -197,26 +188,22 @@ class JdbcAggregateChangeExecutionContext {
private Object getParentId(DbAction.WithDependingOn<?> action) {
PersistentPropertyPathExtension path = new PersistentPropertyPathExtension(context, action.getPropertyPath());
PersistentPropertyPathExtension idPath = path.getIdDefiningParentPath();
DbAction.WithEntity<?> idOwningAction = getIdOwningAction(action, idPath);
DbAction.WithEntity<?> idOwningAction = getIdOwningAction(action, context.getAggregatePath(action.getPropertyPath()).getIdDefiningParentPath());
return getPotentialGeneratedIdFrom(idOwningAction);
}
private DbAction.WithEntity<?> getIdOwningAction(DbAction.WithEntity<?> action,
PersistentPropertyPathExtension idPath) {
private DbAction.WithEntity<?> getIdOwningAction(DbAction.WithEntity<?> action, AggregatePath idPath) {
if (!(action instanceof DbAction.WithDependingOn<?> withDependingOn)) {
Assert.state(idPath.getLength() == 0,
Assert.state(idPath.isRoot(),
"When the id path is not empty the id providing action should be of type WithDependingOn");
return action;
}
if (idPath.matches(withDependingOn.getPropertyPath())) {
if (idPath.equals(context.getAggregatePath(withDependingOn.getPropertyPath()))) {
return action;
}

View File

@@ -47,7 +47,8 @@ import org.springframework.data.mapping.model.SpELExpressionEvaluator;
import org.springframework.data.mapping.model.SpELExpressionParameterValueProvider;
import org.springframework.data.relational.core.conversion.BasicRelationalConverter;
import org.springframework.data.relational.core.conversion.RelationalConverter;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.mapping.AggregatePath;
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.relational.core.sql.IdentifierProcessing;
@@ -86,14 +87,14 @@ public class BasicJdbcConverter extends BasicRelationalConverter implements Jdbc
* Creates a new {@link BasicRelationalConverter} given {@link MappingContext} and a
* {@link JdbcTypeFactory#unsupported() no-op type factory} throwing {@link UnsupportedOperationException} on type
* creation. Use
* {@link #BasicJdbcConverter(MappingContext, RelationResolver, CustomConversions, JdbcTypeFactory, IdentifierProcessing)}
* {@link #BasicJdbcConverter(RelationalMappingContext, RelationResolver, CustomConversions, JdbcTypeFactory, IdentifierProcessing)}
* (MappingContext, RelationResolver, JdbcTypeFactory)} to convert arrays and large objects into JDBC-specific types.
*
* @param context must not be {@literal null}.
* @param relationResolver used to fetch additional relations from the database. Must not be {@literal null}.
*/
public BasicJdbcConverter(
MappingContext<? extends RelationalPersistentEntity<?>, ? extends RelationalPersistentProperty> context,
RelationalMappingContext context,
RelationResolver relationResolver) {
super(context, new JdbcCustomConversions());
@@ -116,7 +117,7 @@ public class BasicJdbcConverter extends BasicRelationalConverter implements Jdbc
* @since 2.0
*/
public BasicJdbcConverter(
MappingContext<? extends RelationalPersistentEntity<?>, ? extends RelationalPersistentProperty> context,
RelationalMappingContext context,
RelationResolver relationResolver, CustomConversions conversions, JdbcTypeFactory typeFactory,
IdentifierProcessing identifierProcessing) {
@@ -300,12 +301,13 @@ public class BasicJdbcConverter extends BasicRelationalConverter implements Jdbc
@Override
public <T> T mapRow(RelationalPersistentEntity<T> entity, ResultSet resultSet, Object key) {
return new ReadingContext<T>(new PersistentPropertyPathExtension(getMappingContext(), entity),
return new ReadingContext<T>(getMappingContext().getAggregatePath( entity),
new ResultSetAccessor(resultSet), Identifier.empty(), key).mapRow();
}
@Override
public <T> T mapRow(PersistentPropertyPathExtension path, ResultSet resultSet, Identifier identifier, Object key) {
public <T> T mapRow(AggregatePath path, ResultSet resultSet, Identifier identifier, Object key) {
return new ReadingContext<T>(path, new ResultSetAccessor(resultSet), identifier, key).mapRow();
}
@@ -350,8 +352,8 @@ public class BasicJdbcConverter extends BasicRelationalConverter implements Jdbc
private final RelationalPersistentEntity<T> entity;
private final PersistentPropertyPathExtension rootPath;
private final PersistentPropertyPathExtension path;
private final AggregatePath rootPath;
private final AggregatePath path;
private final Identifier identifier;
private final Object key;
@@ -360,7 +362,7 @@ public class BasicJdbcConverter extends BasicRelationalConverter implements Jdbc
private final ResultSetAccessor accessor;
@SuppressWarnings("unchecked")
private ReadingContext(PersistentPropertyPathExtension rootPath, ResultSetAccessor accessor, Identifier identifier,
private ReadingContext(AggregatePath rootPath, ResultSetAccessor accessor, Identifier identifier,
Object key) {
RelationalPersistentEntity<T> entity = (RelationalPersistentEntity<T>) rootPath.getLeafEntity();
@@ -368,7 +370,7 @@ public class BasicJdbcConverter extends BasicRelationalConverter implements Jdbc
this.entity = entity;
this.rootPath = rootPath;
this.path = new PersistentPropertyPathExtension(getMappingContext(), this.entity);
this.path = getMappingContext().getAggregatePath( this.entity);
this.identifier = identifier;
this.key = key;
this.propertyValueProvider = new JdbcPropertyValueProvider(path, accessor);
@@ -376,10 +378,11 @@ public class BasicJdbcConverter extends BasicRelationalConverter implements Jdbc
this.accessor = accessor;
}
private ReadingContext(RelationalPersistentEntity<T> entity, PersistentPropertyPathExtension rootPath,
PersistentPropertyPathExtension path, Identifier identifier, Object key,
private ReadingContext(RelationalPersistentEntity<T> entity, AggregatePath rootPath,
AggregatePath path, Identifier identifier, Object key,
JdbcPropertyValueProvider propertyValueProvider,
JdbcBackReferencePropertyValueProvider backReferencePropertyValueProvider, ResultSetAccessor accessor) {
this.entity = entity;
this.rootPath = rootPath;
this.path = path;
@@ -393,7 +396,7 @@ public class BasicJdbcConverter extends BasicRelationalConverter implements Jdbc
private <S> ReadingContext<S> extendBy(RelationalPersistentProperty property) {
return new ReadingContext<>(
(RelationalPersistentEntity<S>) getMappingContext().getRequiredPersistentEntity(property.getActualType()),
rootPath.extendBy(property), path.extendBy(property), identifier, key,
rootPath.append(property), path.append(property), identifier, key,
propertyValueProvider.extendBy(property), backReferencePropertyValueProvider.extendBy(property), accessor);
}
@@ -453,10 +456,10 @@ public class BasicJdbcConverter extends BasicRelationalConverter implements Jdbc
private Iterable<Object> resolveRelation(@Nullable Object id, RelationalPersistentProperty property) {
Identifier identifier = id == null //
? this.identifier.withPart(rootPath.getQualifierColumn(), key, Object.class) //
: Identifier.of(rootPath.extendBy(property).getReverseColumnName(), id, Object.class);
? this.identifier.withPart(rootPath.getTableInfo().qualifierColumnInfo().name(), key, Object.class) //
: Identifier.of(rootPath.append(property).getTableInfo().reverseColumnInfo().name(), id, Object.class);
PersistentPropertyPath<? extends RelationalPersistentProperty> propertyPath = path.extendBy(property)
PersistentPropertyPath<? extends RelationalPersistentProperty> propertyPath = path.append(property)
.getRequiredPersistentPropertyPath();
return relationResolver.findAllByPath(identifier, propertyPath);

View File

@@ -28,12 +28,12 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.relational.core.conversion.IdValueSource;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
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.relational.core.query.Query;
import org.springframework.data.relational.core.sql.IdentifierProcessing;
import org.springframework.data.relational.core.sql.LockMode;
import org.springframework.data.relational.core.sql.SqlIdentifier;
import org.springframework.jdbc.core.RowMapper;
@@ -297,8 +297,8 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
Assert.notNull(identifier, "identifier must not be null");
Assert.notNull(propertyPath, "propertyPath must not be null");
PersistentPropertyPathExtension path = new PersistentPropertyPathExtension(context, propertyPath);
Class<?> actualType = path.getActualType();
AggregatePath path = context.getAggregatePath(propertyPath);
Class<?> actualType = path.getLeafEntity().getType();
String findAllByProperty = sql(actualType) //
.getFindAllByProperty(identifier, propertyPath);
@@ -339,8 +339,7 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
String sqlQuery = sql(domainType).selectByQuery(query, parameterSource);
try {
return Optional.ofNullable(
operations.queryForObject(sqlQuery, parameterSource, getEntityRowMapper(domainType)));
return Optional.ofNullable(operations.queryForObject(sqlQuery, parameterSource, getEntityRowMapper(domainType)));
} catch (EmptyResultDataAccessException e) {
return Optional.empty();
}
@@ -394,14 +393,15 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
return new EntityRowMapper<>(getRequiredPersistentEntity(domainType), converter);
}
private EntityRowMapper<?> getEntityRowMapper(PersistentPropertyPathExtension path, Identifier identifier) {
private EntityRowMapper<?> getEntityRowMapper(AggregatePath path, Identifier identifier) {
return new EntityRowMapper<>(path, converter, identifier);
}
private RowMapper<?> getMapEntityRowMapper(PersistentPropertyPathExtension path, Identifier identifier) {
private RowMapper<?> getMapEntityRowMapper(AggregatePath path, Identifier identifier) {
SqlIdentifier keyColumn = path.getQualifierColumn();
Assert.notNull(keyColumn, () -> "KeyColumn must not be null for " + path);
AggregatePath.ColumnInfo qualifierColumnInfo = path.getTableInfo().qualifierColumnInfo();
Assert.notNull(qualifierColumnInfo, () -> "Qualifier column must not be null for " + path);
SqlIdentifier keyColumn = qualifierColumnInfo.name();
return new MapEntityRowMapper<>(path, converter, identifier, keyColumn);
}

View File

@@ -17,6 +17,7 @@ package org.springframework.data.jdbc.core.convert;
import java.sql.ResultSet;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.jdbc.core.RowMapper;
@@ -35,13 +36,28 @@ import org.springframework.jdbc.core.RowMapper;
public class EntityRowMapper<T> implements RowMapper<T> {
private final RelationalPersistentEntity<T> entity;
private final PersistentPropertyPathExtension path;
private final AggregatePath path;
private final JdbcConverter converter;
private final Identifier identifier;
/**
*
*
* @deprecated use {@link EntityRowMapper#EntityRowMapper(AggregatePath, JdbcConverter, Identifier)} instead
*/
@Deprecated(since = "3.2", forRemoval = true)
@SuppressWarnings("unchecked")
public EntityRowMapper(PersistentPropertyPathExtension path, JdbcConverter converter, Identifier identifier) {
this.entity = (RelationalPersistentEntity<T>) path.getLeafEntity();
this.path = path.getAggregatePath();
this.converter = converter;
this.identifier = identifier;
}
@SuppressWarnings("unchecked")
public EntityRowMapper(AggregatePath path, JdbcConverter converter, Identifier identifier) {
this.entity = (RelationalPersistentEntity<T>) path.getLeafEntity();
this.path = path;
this.converter = converter;

View File

@@ -16,9 +16,8 @@
package org.springframework.data.jdbc.core.convert;
import org.springframework.data.mapping.model.PropertyValueProvider;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.data.relational.core.sql.IdentifierProcessing;
/**
* {@link PropertyValueProvider} obtaining values from a {@link ResultSetAccessor}. For a given id property it provides
@@ -31,14 +30,14 @@ import org.springframework.data.relational.core.sql.IdentifierProcessing;
*/
class JdbcBackReferencePropertyValueProvider implements PropertyValueProvider<RelationalPersistentProperty> {
private final PersistentPropertyPathExtension basePath;
private final AggregatePath basePath;
private final ResultSetAccessor resultSet;
/**
* @param basePath path from the aggregate root relative to which all properties get resolved.
* @param resultSet the {@link ResultSetAccessor} from which to obtain the actual values.
*/
JdbcBackReferencePropertyValueProvider(PersistentPropertyPathExtension basePath, ResultSetAccessor resultSet) {
JdbcBackReferencePropertyValueProvider(AggregatePath basePath, ResultSetAccessor resultSet) {
this.resultSet = resultSet;
this.basePath = basePath;
@@ -46,10 +45,10 @@ class JdbcBackReferencePropertyValueProvider implements PropertyValueProvider<Re
@Override
public <T> T getPropertyValue(RelationalPersistentProperty property) {
return (T) resultSet.getObject(basePath.extendBy(property).getReverseColumnNameAlias().getReference());
return (T) resultSet.getObject(basePath.append(property).getTableInfo().reverseColumnInfo().alias().getReference());
}
public JdbcBackReferencePropertyValueProvider extendBy(RelationalPersistentProperty property) {
return new JdbcBackReferencePropertyValueProvider(basePath.extendBy(property), resultSet);
return new JdbcBackReferencePropertyValueProvider(basePath.append(property), resultSet);
}
}

View File

@@ -19,8 +19,11 @@ import java.sql.ResultSet;
import java.sql.SQLType;
import org.springframework.data.jdbc.core.mapping.JdbcValue;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.relational.core.conversion.RelationalConverter;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
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;
@@ -67,8 +70,24 @@ public interface JdbcConverter extends RelationalConverter {
* @param key primary key.
* @param <T>
* @return
* @deprecated use {@link #mapRow(AggregatePath, ResultSet, Identifier, Object)} instead.
*/
<T> T mapRow(PersistentPropertyPathExtension path, ResultSet resultSet, Identifier identifier, Object key);
@Deprecated(since = "3.2", forRemoval = true)
default <T> T mapRow(PersistentPropertyPathExtension path, ResultSet resultSet, Identifier identifier, Object key){
return mapRow(path.getAggregatePath(), resultSet, identifier, key);
};
/**
* Read the current row from {@link ResultSet} to an {@link AggregatePath#getLeafEntity()} entity}.
*
* @param path path to the owning property.
* @param resultSet the {@link ResultSet} to read from.
* @param identifier entity identifier.
* @param key primary key.
* @param <T>
* @return
*/
<T> T mapRow(AggregatePath path, ResultSet resultSet, Identifier identifier, Object key);
/**
* The type to be used to store this property in the database. Multidimensional arrays are unwrapped to reflect a
@@ -88,4 +107,7 @@ public interface JdbcConverter extends RelationalConverter {
* @since 2.0
*/
SQLType getTargetSqlType(RelationalPersistentProperty property);
@Override
RelationalMappingContext getMappingContext();
}

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.jdbc.core.convert;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
@@ -39,12 +40,23 @@ public class JdbcIdentifierBuilder {
/**
* Creates ParentKeys with backreference for the given path and value of the parents id.
*
* @deprecated Use {@link #forBackReferences(JdbcConverter, AggregatePath, Object)} instead.
*/
@Deprecated(since = "3.2", forRemoval = true)
public static JdbcIdentifierBuilder forBackReferences(JdbcConverter converter, PersistentPropertyPathExtension path,
@Nullable Object value) {
return forBackReferences(converter, path.getAggregatePath(), value);
}
/**
* Creates ParentKeys with backreference for the given path and value of the parents id.
*/
public static JdbcIdentifierBuilder forBackReferences(JdbcConverter converter, AggregatePath path,
@Nullable Object value) {
Identifier identifier = Identifier.of( //
path.getReverseColumnName(), //
path.getTableInfo().reverseColumnInfo().name(), //
value, //
converter.getColumnType(path.getIdDefiningParentPath().getRequiredIdProperty()) //
);
@@ -59,12 +71,26 @@ public class JdbcIdentifierBuilder {
* @param value map key or list index qualifying the map identified by {@code path}. Must not be {@literal null}.
* @return this builder. Guaranteed to be not {@literal null}.
*/
@Deprecated
public JdbcIdentifierBuilder withQualifier(PersistentPropertyPathExtension path, Object value) {
return withQualifier(path.getAggregatePath(), value);
}
/**
* Adds a qualifier to the identifier to build. A qualifier is a map key or a list index.
*
* @param path path to the map that gets qualified by {@code value}. Must not be {@literal null}.
* @param value map key or list index qualifying the map identified by {@code path}. Must not be {@literal null}.
* @return this builder. Guaranteed to be not {@literal null}.
*/
public JdbcIdentifierBuilder withQualifier(AggregatePath path, Object value) {
Assert.notNull(path, "Path must not be null");
Assert.notNull(value, "Value must not be null");
identifier = identifier.withPart(path.getQualifierColumn(), value, path.getQualifierColumnType());
identifier = identifier.withPart(path.getTableInfo().qualifierColumnInfo().name(), value, path.getTableInfo().qualifierColumnType());
return this;
}

View File

@@ -16,9 +16,8 @@
package org.springframework.data.jdbc.core.convert;
import org.springframework.data.mapping.model.PropertyValueProvider;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.data.relational.core.sql.IdentifierProcessing;
/**
* {@link PropertyValueProvider} obtaining values from a {@link ResultSetAccessor}.
@@ -29,15 +28,14 @@ import org.springframework.data.relational.core.sql.IdentifierProcessing;
*/
class JdbcPropertyValueProvider implements PropertyValueProvider<RelationalPersistentProperty> {
private final PersistentPropertyPathExtension basePath;
private final AggregatePath basePath;
private final ResultSetAccessor resultSet;
/**
* @param basePath path from the aggregate root relative to which all properties get resolved.
* @param resultSet the {@link ResultSetAccessor} from which to obtain the actual values.
*/
JdbcPropertyValueProvider(PersistentPropertyPathExtension basePath,
ResultSetAccessor resultSet) {
JdbcPropertyValueProvider(AggregatePath basePath, ResultSetAccessor resultSet) {
this.resultSet = resultSet;
this.basePath = basePath;
@@ -59,10 +57,11 @@ class JdbcPropertyValueProvider implements PropertyValueProvider<RelationalPersi
}
private String getColumnName(RelationalPersistentProperty property) {
return basePath.extendBy(property).getColumnAlias().getReference();
AggregatePath.ColumnInfo columnInfo = basePath.append(property).getColumnInfo();
return columnInfo.alias().getReference();
}
public JdbcPropertyValueProvider extendBy(RelationalPersistentProperty property) {
return new JdbcPropertyValueProvider(basePath.extendBy(property), resultSet);
return new JdbcPropertyValueProvider(basePath.append(property), resultSet);
}
}

View File

@@ -20,6 +20,7 @@ import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.sql.IdentifierProcessing;
import org.springframework.data.relational.core.sql.SqlIdentifier;
@@ -35,12 +36,13 @@ import org.springframework.jdbc.core.RowMapper;
*/
class MapEntityRowMapper<T> implements RowMapper<Map.Entry<Object, T>> {
private final PersistentPropertyPathExtension path;
private final AggregatePath path;
private final JdbcConverter converter;
private final Identifier identifier;
private final SqlIdentifier keyColumn;
MapEntityRowMapper(PersistentPropertyPathExtension path, JdbcConverter converter, Identifier identifier, SqlIdentifier keyColumn) {
MapEntityRowMapper(AggregatePath path, JdbcConverter converter, Identifier identifier, SqlIdentifier keyColumn) {
this.path = path;
this.converter = converter;
this.identifier = identifier;

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.data.jdbc.core.convert;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.sql.Column;
import org.springframework.data.relational.core.sql.SqlIdentifier;
@@ -52,18 +52,20 @@ class SqlContext {
return table;
}
Table getTable(PersistentPropertyPathExtension path) {
Table getTable(AggregatePath path) {
SqlIdentifier tableAlias = path.getTableAlias();
Table table = Table.create(path.getQualifiedTableName());
SqlIdentifier tableAlias = path.getTableInfo().tableAlias();
Table table = Table.create(path.getTableInfo().qualifiedTableName());
return tableAlias == null ? table : table.as(tableAlias);
}
Column getColumn(PersistentPropertyPathExtension path) {
return getTable(path).column(path.getColumnName()).as(path.getColumnAlias());
Column getColumn(AggregatePath path) {
AggregatePath.ColumnInfo columnInfo = path.getColumnInfo();
AggregatePath.ColumnInfo columnInfo1 = path.getColumnInfo();
return getTable(path).column(columnInfo1.name()).as(columnInfo.alias());
}
Column getReverseColumn(PersistentPropertyPathExtension path) {
return getTable(path).column(path.getReverseColumnName()).as(path.getReverseColumnNameAlias());
Column getReverseColumn(AggregatePath path) {
return getTable(path).column(path.getTableInfo().reverseColumnInfo().name()).as(path.getTableInfo().reverseColumnInfo().alias());
}
}

View File

@@ -26,7 +26,7 @@ import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.dialect.RenderContextFactory;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
@@ -66,8 +66,13 @@ class SqlGenerator {
static final SqlIdentifier IDS_SQL_PARAMETER = SqlIdentifier.unquoted("ids");
static final SqlIdentifier ROOT_ID_PARAMETER = SqlIdentifier.unquoted("rootId");
/**
* Length of an aggregate path that is one longer then the root path.
*/
private static final int FIRST_NON_ROOT_LENTH = 2;
private final RelationalPersistentEntity<?> entity;
private final MappingContext<RelationalPersistentEntity<?>, RelationalPersistentProperty> mappingContext;
private final RelationalMappingContext mappingContext;
private final RenderContext renderContext;
private final SqlContext sqlContext;
@@ -112,6 +117,40 @@ class SqlGenerator {
this.dialect = dialect;
}
/**
* When deleting entities there is a fundamental difference between deleting
* <ol>
* <li>the aggregate root.</li>
* <li>a first level entity which still references the root id directly</li>
* <li>and all other entities which have to use a subselect to navigate from the id of the aggregate root to something
* referenced by the table in question.</li>
* </ol>
* For paths of the second kind this method returns {@literal true}.
*
* @param path the path to analyze.
* @return If the given path is considered deeply nested.
*/
private static boolean isFirstNonRoot(AggregatePath path) {
return path.getLength() == FIRST_NON_ROOT_LENTH;
}
/**
* When deleting entities there is a fundamental difference between deleting
* <ol>
* <li>the aggregate root.</li>
* <li>a first level entity which still references the root id directly</li>
* <li>and all other entities which have to use a subselect to navigate from the id of the aggregate root to something
* referenced by the table in question.</li>
* </ol>
* For paths of the third kind this method returns {@literal true}.
*
* @param path the path to analyze.
* @return If the given path is considered deeply nested.
*/
private static boolean isDeeplyNested(AggregatePath path) {
return path.getLength() > FIRST_NON_ROOT_LENTH;
}
/**
* Construct an IN-condition based on a {@link Select Sub-Select} which selects the ids (or stand-ins for ids) of the
* given {@literal path} to those that reference the root entities specified by the {@literal rootCondition}.
@@ -121,25 +160,25 @@ class SqlGenerator {
* @param filterColumn the column to apply the IN-condition to.
* @return the IN condition
*/
private Condition getSubselectCondition(PersistentPropertyPathExtension path,
Function<Column, Condition> rootCondition, Column filterColumn) {
private Condition getSubselectCondition(AggregatePath path, Function<Column, Condition> rootCondition,
Column filterColumn) {
PersistentPropertyPathExtension parentPath = path.getParentPath();
AggregatePath parentPath = path.getParentPath();
if (!parentPath.hasIdProperty()) {
if (parentPath.getLength() > 1) {
if (isDeeplyNested(parentPath)) {
return getSubselectCondition(parentPath, rootCondition, filterColumn);
}
return rootCondition.apply(filterColumn);
}
Table subSelectTable = Table.create(parentPath.getQualifiedTableName());
Column idColumn = subSelectTable.column(parentPath.getIdColumnName());
Column selectFilterColumn = subSelectTable.column(parentPath.getEffectiveIdColumnName());
Table subSelectTable = Table.create(parentPath.getTableInfo().qualifiedTableName());
Column idColumn = subSelectTable.column(parentPath.getTableInfo().idColumnName());
Column selectFilterColumn = subSelectTable.column(parentPath.getTableInfo().effectiveIdColumnName());
Condition innerCondition;
if (parentPath.getLength() == 1) { // if the parent is the root of the path
if (isFirstNonRoot(parentPath)) { // if the parent is the root of the path
// apply the rootCondition
innerCondition = rootCondition.apply(selectFilterColumn);
@@ -216,9 +255,9 @@ class SqlGenerator {
Assert.notNull(parentIdentifier, "identifier must not be null");
Assert.notNull(propertyPath, "propertyPath must not be null");
PersistentPropertyPathExtension path = new PersistentPropertyPathExtension(mappingContext, propertyPath);
AggregatePath path = mappingContext.getAggregatePath(propertyPath);
return getFindAllByProperty(parentIdentifier, path.getQualifierColumn(), path.isOrdered());
return getFindAllByProperty(parentIdentifier, path.getTableInfo().qualifierColumnInfo(), path.isOrdered());
}
/**
@@ -233,7 +272,8 @@ class SqlGenerator {
* keyColumn must not be {@code null}.
* @return a SQL String.
*/
String getFindAllByProperty(Identifier parentIdentifier, @Nullable SqlIdentifier keyColumn, boolean ordered) {
String getFindAllByProperty(Identifier parentIdentifier, @Nullable AggregatePath.ColumnInfo keyColumn,
boolean ordered) {
Assert.isTrue(keyColumn != null || !ordered,
"If the SQL statement should be ordered a keyColumn to order by must be provided");
@@ -243,14 +283,14 @@ class SqlGenerator {
SelectBuilder.SelectWhere builder = selectBuilder( //
keyColumn == null //
? Collections.emptyList() //
: Collections.singleton(keyColumn) //
: Collections.singleton(keyColumn.name()) //
);
Condition condition = buildConditionForBackReference(parentIdentifier, table);
SelectBuilder.SelectWhereAndOr withWhereClause = builder.where(condition);
Select select = ordered //
? withWhereClause.orderBy(table.column(keyColumn).as(keyColumn)).build() //
? withWhereClause.orderBy(table.column(keyColumn.name()).as(keyColumn.alias())).build() //
: withWhereClause.build();
return render(select);
@@ -399,7 +439,7 @@ class SqlGenerator {
return render(deleteAll.build());
}
return createDeleteByPathAndCriteria(new PersistentPropertyPathExtension(mappingContext, path), Column::isNotNull);
return createDeleteByPathAndCriteria(mappingContext.getAggregatePath(path), Column::isNotNull);
}
/**
@@ -410,7 +450,7 @@ class SqlGenerator {
* @return the statement as a {@link String}. Guaranteed to be not {@literal null}.
*/
String createDeleteByPath(PersistentPropertyPath<RelationalPersistentProperty> path) {
return createDeleteByPathAndCriteria(new PersistentPropertyPathExtension(mappingContext, path),
return createDeleteByPathAndCriteria(mappingContext.getAggregatePath(path),
filterColumn -> filterColumn.isEqualTo(getBindMarker(ROOT_ID_PARAMETER)));
}
@@ -423,7 +463,7 @@ class SqlGenerator {
*/
String createDeleteInByPath(PersistentPropertyPath<RelationalPersistentProperty> path) {
return createDeleteByPathAndCriteria(new PersistentPropertyPathExtension(mappingContext, path),
return createDeleteByPathAndCriteria(mappingContext.getAggregatePath(path),
filterColumn -> filterColumn.in(getBindMarker(IDS_SQL_PARAMETER)));
}
@@ -480,7 +520,7 @@ class SqlGenerator {
for (PersistentPropertyPath<RelationalPersistentProperty> path : mappingContext
.findPersistentPropertyPaths(entity.getType(), p -> true)) {
PersistentPropertyPathExtension extPath = new PersistentPropertyPathExtension(mappingContext, path);
AggregatePath extPath = mappingContext.getAggregatePath(path);
// add a join if necessary
Join join = getJoin(extPath);
@@ -537,13 +577,13 @@ class SqlGenerator {
}
/**
* Create a {@link Column} for {@link PersistentPropertyPathExtension}.
* Create a {@link Column} for {@link AggregatePath}.
*
* @param path the path to the column in question.
* @return the statement as a {@link String}. Guaranteed to be not {@literal null}.
*/
@Nullable
Column getColumn(PersistentPropertyPathExtension path) {
Column getColumn(AggregatePath path) {
// an embedded itself doesn't give a column, its members will though.
// if there is a collection or map on the path it won't get selected at all, but it will get loaded with a separate
@@ -572,7 +612,7 @@ class SqlGenerator {
}
@Nullable
Join getJoin(PersistentPropertyPathExtension path) {
Join getJoin(AggregatePath path) {
if (!path.isEntity() || path.isEmbedded() || path.isMultiValued()) {
return null;
@@ -580,13 +620,13 @@ class SqlGenerator {
Table currentTable = sqlContext.getTable(path);
PersistentPropertyPathExtension idDefiningParentPath = path.getIdDefiningParentPath();
AggregatePath idDefiningParentPath = path.getIdDefiningParentPath();
Table parentTable = sqlContext.getTable(idDefiningParentPath);
return new Join( //
currentTable, //
currentTable.column(path.getReverseColumnName()), //
parentTable.column(idDefiningParentPath.getIdColumnName()) //
currentTable.column(path.getTableInfo().reverseColumnInfo().name()), //
parentTable.column(idDefiningParentPath.getTableInfo().idColumnName()) //
);
}
@@ -707,18 +747,17 @@ class SqlGenerator {
.where(getIdColumn().in(getBindMarker(IDS_SQL_PARAMETER)));
}
private String createDeleteByPathAndCriteria(PersistentPropertyPathExtension path,
Function<Column, Condition> rootCondition) {
private String createDeleteByPathAndCriteria(AggregatePath path, Function<Column, Condition> rootCondition) {
Table table = Table.create(path.getQualifiedTableName());
Table table = Table.create(path.getTableInfo().qualifiedTableName());
DeleteBuilder.DeleteWhere builder = Delete.builder() //
.from(table);
Delete delete;
Column filterColumn = table.column(path.getReverseColumnName());
Column filterColumn = table.column(path.getTableInfo().reverseColumnInfo().name());
if (path.getLength() == 1) {
if (isFirstNonRoot(path)) {
delete = builder //
.where(rootCondition.apply(filterColumn)) //
@@ -926,10 +965,10 @@ class SqlGenerator {
for (PersistentPropertyPath<RelationalPersistentProperty> path : mappingContext
.findPersistentPropertyPaths(entity.getType(), p -> true)) {
PersistentPropertyPathExtension extPath = new PersistentPropertyPathExtension(mappingContext, path);
AggregatePath aggregatePath = mappingContext.getAggregatePath(path);
// add a join if necessary
Join join = getJoin(extPath);
Join join = getJoin(aggregatePath);
if (join != null) {
baseSelect = baseSelect.leftOuterJoin(join.joinTable).on(join.joinColumn).equals(join.parentId);
}
@@ -960,7 +999,7 @@ class SqlGenerator {
for (PersistentPropertyPath<RelationalPersistentProperty> path : mappingContext
.findPersistentPropertyPaths(entity.getType(), p -> true)) {
PersistentPropertyPathExtension extPath = new PersistentPropertyPathExtension(mappingContext, path);
AggregatePath extPath = mappingContext.getAggregatePath(path);
// add a join if necessary
Join join = getJoin(extPath);

View File

@@ -25,10 +25,9 @@ import org.springframework.data.domain.Sort;
import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.core.convert.QueryMapper;
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.dialect.RenderContextFactory;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
@@ -117,8 +116,7 @@ class JdbcQueryCreator extends RelationalQueryCreator<ParametrizedQuery> {
* @param tree the tree structure defining the predicate of the query.
* @param parameters parameters for the predicate.
*/
static void validate(PartTree tree, Parameters<?, ?> parameters,
MappingContext<? extends RelationalPersistentEntity<?>, ? extends RelationalPersistentProperty> context) {
static void validate(PartTree tree, Parameters<?, ?> parameters, RelationalMappingContext context) {
RelationalQueryCreator.validate(tree, parameters);
@@ -127,30 +125,30 @@ class JdbcQueryCreator extends RelationalQueryCreator<ParametrizedQuery> {
PersistentPropertyPath<? extends RelationalPersistentProperty> propertyPath = context
.getPersistentPropertyPath(part.getProperty());
PersistentPropertyPathExtension path = new PersistentPropertyPathExtension(context, propertyPath);
AggregatePath path = context.getAggregatePath(propertyPath);
for (PersistentPropertyPathExtension pathToValidate = path; path.getLength() > 0; path = path.getParentPath()) {
validateProperty(pathToValidate);
}
path.forEach(JdbcQueryCreator::validateProperty);
}
}
}
private static void validateProperty(PersistentPropertyPathExtension path) {
private static void validateProperty(AggregatePath path) {
if (!path.getParentPath().isEmbedded() && path.getLength() > 1) {
throw new IllegalArgumentException(
String.format("Cannot query by nested property: %s", path.getRequiredPersistentPropertyPath().toDotPath()));
if (path.isRoot()) {
return;
}
if (!path.getParentPath().isEmbedded() && path.getLength() > 2) {
throw new IllegalArgumentException(String.format("Cannot query by nested property: %s", path.toDotPath()));
}
if (path.isMultiValued() || path.isMap()) {
throw new IllegalArgumentException(String.format("Cannot query by multi-valued property: %s",
path.getRequiredPersistentPropertyPath().getLeafProperty().getName()));
throw new IllegalArgumentException(
String.format("Cannot query by multi-valued property: %s", path.getRequiredLeafProperty().getName()));
}
if (!path.isEmbedded() && path.isEntity()) {
throw new IllegalArgumentException(
String.format("Cannot query by nested entity: %s", path.getRequiredPersistentPropertyPath().toDotPath()));
throw new IllegalArgumentException(String.format("Cannot query by nested entity: %s", path.toDotPath()));
}
}
@@ -245,22 +243,21 @@ class JdbcQueryCreator extends RelationalQueryCreator<ParametrizedQuery> {
for (PersistentPropertyPath<RelationalPersistentProperty> path : context
.findPersistentPropertyPaths(entity.getType(), p -> true)) {
PersistentPropertyPathExtension extPath = new PersistentPropertyPathExtension(context, path);
AggregatePath aggregatePath = context.getAggregatePath(path);
if (returnedType.needsCustomConstruction()) {
if (!returnedType.getInputProperties()
.contains(extPath.getRequiredPersistentPropertyPath().getBaseProperty().getName())) {
if (!returnedType.getInputProperties().contains(aggregatePath.getRequiredBaseProperty().getName())) {
continue;
}
}
// add a join if necessary
Join join = getJoin(sqlContext, extPath);
Join join = getJoin(sqlContext, aggregatePath);
if (join != null) {
joinTables.add(join);
}
Column column = getColumn(sqlContext, extPath);
Column column = getColumn(sqlContext, aggregatePath);
if (column != null) {
columnExpressions.add(column);
}
@@ -277,14 +274,14 @@ class JdbcQueryCreator extends RelationalQueryCreator<ParametrizedQuery> {
}
/**
* Create a {@link Column} for {@link PersistentPropertyPathExtension}.
* Create a {@link Column} for {@link AggregatePath}.
*
* @param sqlContext
* @param path the path to the column in question.
* @return the statement as a {@link String}. Guaranteed to be not {@literal null}.
*/
@Nullable
private Column getColumn(SqlContext sqlContext, PersistentPropertyPathExtension path) {
private Column getColumn(SqlContext sqlContext, AggregatePath path) {
// an embedded itself doesn't give an column, its members will though.
// if there is a collection or map on the path it won't get selected at all, but it will get loaded with a separate
@@ -313,7 +310,7 @@ class JdbcQueryCreator extends RelationalQueryCreator<ParametrizedQuery> {
}
@Nullable
Join getJoin(SqlContext sqlContext, PersistentPropertyPathExtension path) {
Join getJoin(SqlContext sqlContext, AggregatePath path) {
if (!path.isEntity() || path.isEmbedded() || path.isMultiValued()) {
return null;
@@ -321,13 +318,13 @@ class JdbcQueryCreator extends RelationalQueryCreator<ParametrizedQuery> {
Table currentTable = sqlContext.getTable(path);
PersistentPropertyPathExtension idDefiningParentPath = path.getIdDefiningParentPath();
AggregatePath idDefiningParentPath = path.getIdDefiningParentPath();
Table parentTable = sqlContext.getTable(idDefiningParentPath);
return new Join( //
currentTable, //
currentTable.column(path.getReverseColumnName()), //
parentTable.column(idDefiningParentPath.getIdColumnName()) //
currentTable.column(path.getTableInfo().reverseColumnInfo().name()), //
parentTable.column(idDefiningParentPath.getTableInfo().idColumnName()) //
);
}

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.data.jdbc.repository.query;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.sql.Column;
import org.springframework.data.relational.core.sql.SqlIdentifier;
@@ -53,18 +53,21 @@ class SqlContext {
return table;
}
Table getTable(PersistentPropertyPathExtension path) {
Table getTable(AggregatePath path) {
SqlIdentifier tableAlias = path.getTableAlias();
Table table = Table.create(path.getQualifiedTableName());
SqlIdentifier tableAlias = path.getTableInfo().tableAlias();
Table table = Table.create(path.getTableInfo().qualifiedTableName());
return tableAlias == null ? table : table.as(tableAlias);
}
Column getColumn(PersistentPropertyPathExtension path) {
return getTable(path).column(path.getColumnName()).as(path.getColumnAlias());
Column getColumn(AggregatePath path) {
AggregatePath.ColumnInfo columnInfo = path.getColumnInfo();
AggregatePath.ColumnInfo columnInfo1 = path.getColumnInfo();
return getTable(path).column(columnInfo1.name()).as(columnInfo.alias());
}
Column getReverseColumn(PersistentPropertyPathExtension path) {
return getTable(path).column(path.getReverseColumnName()).as(path.getReverseColumnNameAlias());
Column getReverseColumn(AggregatePath path) {
return getTable(path).column(path.getTableInfo().reverseColumnInfo().name())
.as(path.getTableInfo().reverseColumnInfo().alias());
}
}

View File

@@ -27,7 +27,7 @@ import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.mapping.PersistentPropertyPaths;
import org.springframework.data.relational.core.conversion.DbAction;
import org.springframework.data.relational.core.conversion.IdValueSource;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.lang.Nullable;
@@ -156,8 +156,8 @@ public class JdbcAggregateChangeExecutorContextImmutableUnitTests {
key == null ? emptyMap() : singletonMap(toPath(propertyName), key), IdValueSource.GENERATED);
}
PersistentPropertyPathExtension toPathExt(String path) {
return new PersistentPropertyPathExtension(context, getPersistentPropertyPath(path));
AggregatePath toAggregatePath(String path) {
return context.getAggregatePath(getPersistentPropertyPath(path));
}
PersistentPropertyPath<RelationalPersistentProperty> getPersistentPropertyPath(String propertyName) {
@@ -165,7 +165,7 @@ public class JdbcAggregateChangeExecutorContextImmutableUnitTests {
}
Identifier createBackRef(long value) {
return JdbcIdentifierBuilder.forBackReferences(converter, toPathExt("content"), value).build();
return JdbcIdentifierBuilder.forBackReferences(converter, toAggregatePath("content"), value).build();
}
PersistentPropertyPath<RelationalPersistentProperty> toPath(String path) {

View File

@@ -34,7 +34,7 @@ import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.mapping.PersistentPropertyPaths;
import org.springframework.data.relational.core.conversion.DbAction;
import org.springframework.data.relational.core.conversion.IdValueSource;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.data.relational.core.sql.SqlIdentifier;
@@ -248,8 +248,8 @@ public class JdbcAggregateChangeExecutorContextUnitTests {
key == null ? emptyMap() : singletonMap(toPath(propertyName), key), idValueSource);
}
PersistentPropertyPathExtension toPathExt(String path) {
return new PersistentPropertyPathExtension(context, getPersistentPropertyPath(path));
AggregatePath toAggregatePath(String path) {
return context.getAggregatePath(getPersistentPropertyPath(path));
}
PersistentPropertyPath<RelationalPersistentProperty> getPersistentPropertyPath(String propertyName) {
@@ -257,7 +257,7 @@ public class JdbcAggregateChangeExecutorContextUnitTests {
}
Identifier createBackRef(long value) {
return forBackReferences(converter, toPathExt("content"), value).build();
return forBackReferences(converter, toAggregatePath("content"), value).build();
}
PersistentPropertyPath<RelationalPersistentProperty> toPath(String path) {

View File

@@ -15,6 +15,7 @@
*/
package org.springframework.data.jdbc.core;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.SoftAssertions.*;
import static org.springframework.data.relational.core.sql.SqlIdentifier.*;
@@ -238,6 +239,14 @@ public class PersistentPropertyPathExtensionUnitTests {
});
}
@Test // GH-1525
void getAggregatePath() {
assertThat(extPath("withId").getAggregatePath()).isNotNull();
}
@Test // GH-1525
void getAggregatePathFromRoot() {
assertThat(extPath(entity).getAggregatePath()).isNotNull();
}
private PersistentPropertyPathExtension extPath(RelationalPersistentEntity<?> entity) {
return new PersistentPropertyPathExtension(context, entity);
}
@@ -247,7 +256,7 @@ public class PersistentPropertyPathExtensionUnitTests {
}
PersistentPropertyPath<RelationalPersistentProperty> createSimplePath(String path) {
return PropertyPathTestingUtils.toPath(path, DummyEntity.class, context);
return PersistentPropertyPathTestUtils.getPath(path, DummyEntity.class, context);
}
@SuppressWarnings("unused")

View File

@@ -26,18 +26,22 @@ import org.springframework.data.relational.core.mapping.RelationalPersistentProp
*
* @author Jens Schauder
*/
public final class PropertyPathTestingUtils {
public final class PersistentPropertyPathTestUtils {
private PropertyPathTestingUtils() {
private PersistentPropertyPathTestUtils() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
public static PersistentPropertyPath<RelationalPersistentProperty> toPath(String path, Class source,
RelationalMappingContext context) {
public static PersistentPropertyPath<RelationalPersistentProperty> getPath(String path, Class source,
RelationalMappingContext context) {
PersistentPropertyPaths<?, RelationalPersistentProperty> persistentPropertyPaths = context
.findPersistentPropertyPaths(source, p -> true);
return persistentPropertyPaths.filter(p -> p.toDotPath().equals(path)).stream().findFirst().orElse(null);
return persistentPropertyPaths
.filter(p -> p.toDotPath().equals(path))
.stream()
.findFirst()
.orElse(null);
}
}

View File

@@ -16,7 +16,6 @@
package org.springframework.data.jdbc.core.convert;
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.jdbc.core.PropertyPathTestingUtils.*;
import static org.springframework.data.relational.core.sql.SqlIdentifier.*;
import java.util.List;
@@ -25,8 +24,9 @@ import java.util.UUID;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.PersistentPropertyPathTestUtils;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.mapping.AggregatePath;
/**
* Unit tests for the {@link JdbcIdentifierBuilder}.
@@ -55,7 +55,7 @@ public class JdbcIdentifierBuilderUnitTests {
@Test // DATAJDBC-326
public void qualifiersForMaps() {
PersistentPropertyPathExtension path = getPath("children");
AggregatePath path = getPath("children");
Identifier identifier = JdbcIdentifierBuilder //
.forBackReferences(converter, path, "parent-eins") //
@@ -73,7 +73,7 @@ public class JdbcIdentifierBuilderUnitTests {
@Test // DATAJDBC-326
public void qualifiersForLists() {
PersistentPropertyPathExtension path = getPath("moreChildren");
AggregatePath path = getPath("moreChildren");
Identifier identifier = JdbcIdentifierBuilder //
.forBackReferences(converter, path, "parent-eins") //
@@ -116,8 +116,8 @@ public class JdbcIdentifierBuilderUnitTests {
);
}
private PersistentPropertyPathExtension getPath(String dotPath) {
return new PersistentPropertyPathExtension(context, toPath(dotPath, DummyEntity.class, context));
private AggregatePath getPath(String dotPath) {
return context.getAggregatePath(PersistentPropertyPathTestUtils.getPath(dotPath, DummyEntity.class, context));
}
@SuppressWarnings("unused")

View File

@@ -26,8 +26,8 @@ import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.PersistentPropertyPathTestUtils;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.core.mapping.PersistentPropertyPathTestUtils;
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.relational.core.mapping.NamingStrategy;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
@@ -157,7 +157,7 @@ public class SqlGeneratorContextBasedNamingStrategyUnitTests {
}
private PersistentPropertyPath<RelationalPersistentProperty> getPath(String path) {
return PersistentPropertyPathTestUtils.getPath(this.context, path, DummyEntity.class);
return PersistentPropertyPathTestUtils.getPath(path, DummyEntity.class, this.context);
}
/**

View File

@@ -23,12 +23,11 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.PropertyPathTestingUtils;
import org.springframework.data.jdbc.core.PersistentPropertyPathTestUtils;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Embedded;
import org.springframework.data.relational.core.mapping.Embedded.OnEmpty;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.sql.Aliased;
@@ -177,7 +176,7 @@ public class SqlGeneratorEmbeddedUnitTests {
public void deleteByPath() {
final String sql = sqlGenerator
.createDeleteByPath(PropertyPathTestingUtils.toPath("embedded.other", DummyEntity2.class, context));
.createDeleteByPath(PersistentPropertyPathTestUtils.getPath("embedded.other", DummyEntity2.class, context));
assertThat(sql).containsSequence("DELETE FROM other_entity", //
"WHERE", //
@@ -295,7 +294,7 @@ public class SqlGeneratorEmbeddedUnitTests {
private SqlGenerator.Join generateJoin(String path, Class<?> type) {
return createSqlGenerator(type)
.getJoin(new PersistentPropertyPathExtension(context, PropertyPathTestingUtils.toPath(path, type, context)));
.getJoin(context.getAggregatePath(PersistentPropertyPathTestUtils.getPath(path, type, context)));
}
@Nullable
@@ -310,13 +309,14 @@ public class SqlGeneratorEmbeddedUnitTests {
private org.springframework.data.relational.core.sql.Column generatedColumn(String path, Class<?> type) {
return createSqlGenerator(type)
.getColumn(new PersistentPropertyPathExtension(context, PropertyPathTestingUtils.toPath(path, type, context)));
.getColumn(context.getAggregatePath(PersistentPropertyPathTestUtils.getPath(path, type, context)));
}
@SuppressWarnings("unused")
static class DummyEntity {
@Column("id1") @Id Long id;
@Column("id1")
@Id Long id;
@Embedded(onEmpty = OnEmpty.USE_NULL, prefix = "prefix_") CascadedEmbedded prefixedEmbeddable;

View File

@@ -21,8 +21,8 @@ import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.PersistentPropertyPathTestUtils;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.core.mapping.PersistentPropertyPathTestUtils;
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.relational.core.dialect.AnsiDialect;
import org.springframework.data.relational.core.mapping.NamingStrategy;
@@ -70,7 +70,7 @@ class SqlGeneratorFixedNamingStrategyUnitTests {
}
};
private RelationalMappingContext context = new JdbcMappingContext();
private RelationalMappingContext context;
@Test // DATAJDBC-107
void findOneWithOverriddenFixedTableName() {
@@ -122,7 +122,7 @@ class SqlGeneratorFixedNamingStrategyUnitTests {
String sql = sqlGenerator.createDeleteByPath(getPath("ref"));
assertThat(sql).isEqualTo("DELETE FROM \"FIXEDCUSTOMSCHEMA\".\"FIXEDCUSTOMTABLEPREFIX_REFERENCEDENTITY\" "
+ "WHERE \"FIXEDCUSTOMSCHEMA\".\"FIXEDCUSTOMTABLEPREFIX_REFERENCEDENTITY\".\"DUMMY_ENTITY\" = :rootId");
+ "WHERE \"FIXEDCUSTOMSCHEMA\".\"FIXEDCUSTOMTABLEPREFIX_REFERENCEDENTITY\".\"FIXEDCUSTOMTABLEPREFIX_DUMMYENTITY\" = :rootId");
}
@Test // DATAJDBC-107
@@ -137,7 +137,7 @@ class SqlGeneratorFixedNamingStrategyUnitTests {
+ "WHERE \"FIXEDCUSTOMSCHEMA\".\"FIXEDCUSTOMTABLEPREFIX_SECONDLEVELREFERENCEDENTITY\".\"FIXEDCUSTOMTABLEPREFIX_REFERENCEDENTITY\" IN "
+ "(SELECT \"FIXEDCUSTOMSCHEMA\".\"FIXEDCUSTOMTABLEPREFIX_REFERENCEDENTITY\".\"FIXEDCUSTOMPROPERTYPREFIX_L1ID\" "
+ "FROM \"FIXEDCUSTOMSCHEMA\".\"FIXEDCUSTOMTABLEPREFIX_REFERENCEDENTITY\" "
+ "WHERE \"FIXEDCUSTOMSCHEMA\".\"FIXEDCUSTOMTABLEPREFIX_REFERENCEDENTITY\".\"DUMMY_ENTITY\" = :rootId)");
+ "WHERE \"FIXEDCUSTOMSCHEMA\".\"FIXEDCUSTOMTABLEPREFIX_REFERENCEDENTITY\".\"FIXEDCUSTOMTABLEPREFIX_DUMMYENTITY\" = :rootId)");
}
@Test // DATAJDBC-107
@@ -158,7 +158,7 @@ class SqlGeneratorFixedNamingStrategyUnitTests {
String sql = sqlGenerator.createDeleteAllSql(getPath("ref"));
assertThat(sql).isEqualTo("DELETE FROM \"FIXEDCUSTOMSCHEMA\".\"FIXEDCUSTOMTABLEPREFIX_REFERENCEDENTITY\" "
+ "WHERE \"FIXEDCUSTOMSCHEMA\".\"FIXEDCUSTOMTABLEPREFIX_REFERENCEDENTITY\".\"DUMMY_ENTITY\" IS NOT NULL");
+ "WHERE \"FIXEDCUSTOMSCHEMA\".\"FIXEDCUSTOMTABLEPREFIX_REFERENCEDENTITY\".\"FIXEDCUSTOMTABLEPREFIX_DUMMYENTITY\" IS NOT NULL");
}
@Test // DATAJDBC-107
@@ -173,7 +173,7 @@ class SqlGeneratorFixedNamingStrategyUnitTests {
+ "WHERE \"FIXEDCUSTOMSCHEMA\".\"FIXEDCUSTOMTABLEPREFIX_SECONDLEVELREFERENCEDENTITY\".\"FIXEDCUSTOMTABLEPREFIX_REFERENCEDENTITY\" IN "
+ "(SELECT \"FIXEDCUSTOMSCHEMA\".\"FIXEDCUSTOMTABLEPREFIX_REFERENCEDENTITY\".\"FIXEDCUSTOMPROPERTYPREFIX_L1ID\" "
+ "FROM \"FIXEDCUSTOMSCHEMA\".\"FIXEDCUSTOMTABLEPREFIX_REFERENCEDENTITY\" "
+ "WHERE \"FIXEDCUSTOMSCHEMA\".\"FIXEDCUSTOMTABLEPREFIX_REFERENCEDENTITY\".\"DUMMY_ENTITY\" IS NOT NULL)");
+ "WHERE \"FIXEDCUSTOMSCHEMA\".\"FIXEDCUSTOMTABLEPREFIX_REFERENCEDENTITY\".\"FIXEDCUSTOMTABLEPREFIX_DUMMYENTITY\" IS NOT NULL)");
}
@Test // DATAJDBC-113
@@ -188,7 +188,7 @@ class SqlGeneratorFixedNamingStrategyUnitTests {
}
private PersistentPropertyPath<RelationalPersistentProperty> getPath(String path) {
return PersistentPropertyPathTestUtils.getPath(context, path, DummyEntity.class);
return PersistentPropertyPathTestUtils.getPath(path, DummyEntity.class, context);
}
/**
@@ -196,7 +196,7 @@ class SqlGeneratorFixedNamingStrategyUnitTests {
*/
private SqlGenerator configureSqlGenerator(NamingStrategy namingStrategy) {
RelationalMappingContext context = new JdbcMappingContext(namingStrategy);
context = new JdbcMappingContext(namingStrategy);
JdbcConverter converter = new BasicJdbcConverter(context, (identifier, path) -> {
throw new UnsupportedOperationException();
});

View File

@@ -32,18 +32,17 @@ import org.springframework.data.annotation.Version;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jdbc.core.PropertyPathTestingUtils;
import org.springframework.data.jdbc.core.PersistentPropertyPathTestUtils;
import org.springframework.data.jdbc.core.mapping.AggregateReference;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.core.mapping.PersistentPropertyPathTestUtils;
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.relational.core.dialect.AnsiDialect;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.dialect.PostgresDialect;
import org.springframework.data.relational.core.dialect.SqlServerDialect;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.DefaultNamingStrategy;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
@@ -389,7 +388,7 @@ class SqlGeneratorUnitTests {
void findAllByPropertyWithKey() {
// this would get called when ListParent is th element type of a Map
String sql = sqlGenerator.getFindAllByProperty(BACKREF, unquoted("key-column"), false);
String sql = sqlGenerator.getFindAllByProperty(BACKREF, new AggregatePath.ColumnInfo(unquoted("key-column"),unquoted("key-column")), false);
assertThat(sql).isEqualTo("SELECT dummy_entity.id1 AS id1, dummy_entity.x_name AS x_name, " //
+ "dummy_entity.x_other AS x_other, " //
@@ -412,7 +411,8 @@ class SqlGeneratorUnitTests {
void findAllByPropertyWithKeyOrdered() {
// this would get called when ListParent is th element type of a Map
String sql = sqlGenerator.getFindAllByProperty(BACKREF, unquoted("key-column"), true);
String sql = sqlGenerator.getFindAllByProperty(BACKREF,
new AggregatePath.ColumnInfo(unquoted("key-column"), unquoted("key-column")), true);
assertThat(sql).isEqualTo("SELECT dummy_entity.id1 AS id1, dummy_entity.x_name AS x_name, " //
+ "dummy_entity.x_other AS x_other, " //
@@ -432,8 +432,10 @@ class SqlGeneratorUnitTests {
final SqlGenerator sqlGenerator = createSqlGenerator(ReferencedEntity.class);
final String sql = sqlGenerator.getFindAllByProperty(
Identifier.of(quoted("id"), "parent-id-value", DummyEntity.class), //
quoted("X_L1ID"), // this key column collides with the name derived by the naming strategy for the id of
// ReferencedEntity.
new AggregatePath.ColumnInfo(quoted("X_L1ID"), quoted("X_L1ID")), // this key column collides with the name
// derived by the naming strategy for the id
// of
// ReferencedEntity.
false);
final String id = "referenced_entity.x_l1id AS x_l1id";
@@ -447,10 +449,11 @@ class SqlGeneratorUnitTests {
void findAllByPropertyWithEmptyBackrefColumn() {
Identifier emptyIdentifier = Identifier.of(EMPTY, 0, Object.class);
assertThatThrownBy(() -> sqlGenerator.getFindAllByProperty(emptyIdentifier, unquoted("key-column"), false)) //
.isInstanceOf(IllegalArgumentException.class) //
.hasMessageContaining(
"An empty SqlIdentifier can't be used in condition. Make sure that all composite primary keys are defined in the query");
assertThatThrownBy(() -> sqlGenerator.getFindAllByProperty(emptyIdentifier,
new AggregatePath.ColumnInfo(unquoted("key-column"), unquoted("key-column")), false)) //
.isInstanceOf(IllegalArgumentException.class) //
.hasMessageContaining(
"An empty SqlIdentifier can't be used in condition. Make sure that all composite primary keys are defined in the query");
}
@Test // DATAJDBC-219
@@ -574,15 +577,16 @@ class SqlGeneratorUnitTests {
final SqlGenerator sqlGenerator = createSqlGenerator(EntityWithReadOnlyProperty.class);
assertThat(sqlGenerator.getFindAllByProperty(BACKREF, unquoted("key-column"), true)).isEqualToIgnoringCase( //
"SELECT " //
+ "entity_with_read_only_property.x_id AS x_id, " //
+ "entity_with_read_only_property.x_name AS x_name, " //
+ "entity_with_read_only_property.x_read_only_value AS x_read_only_value, " //
+ "entity_with_read_only_property.key-column AS key-column " //
+ "FROM entity_with_read_only_property " //
+ "WHERE entity_with_read_only_property.backref = :backref " //
+ "ORDER BY key-column" //
assertThat(sqlGenerator.getFindAllByProperty(BACKREF,
new AggregatePath.ColumnInfo(unquoted("key-column"), unquoted("key-column")), true)).isEqualToIgnoringCase( //
"SELECT " //
+ "entity_with_read_only_property.x_id AS x_id, " //
+ "entity_with_read_only_property.x_name AS x_name, " //
+ "entity_with_read_only_property.x_read_only_value AS x_read_only_value, " //
+ "entity_with_read_only_property.key-column AS key-column " //
+ "FROM entity_with_read_only_property " //
+ "WHERE entity_with_read_only_property.backref = :backref " //
+ "ORDER BY key-column" //
);
}
@@ -736,7 +740,7 @@ class SqlGeneratorUnitTests {
@Nullable
private SqlGenerator.Join generateJoin(String path, Class<?> type) {
return createSqlGenerator(type, AnsiDialect.INSTANCE)
.getJoin(new PersistentPropertyPathExtension(context, PropertyPathTestingUtils.toPath(path, type, context)));
.getJoin(context.getAggregatePath(PersistentPropertyPathTestUtils.getPath(path, type, context)));
}
@Test // DATAJDBC-340
@@ -935,11 +939,11 @@ class SqlGeneratorUnitTests {
private org.springframework.data.relational.core.sql.Column generatedColumn(String path, Class<?> type) {
return createSqlGenerator(type, AnsiDialect.INSTANCE)
.getColumn(new PersistentPropertyPathExtension(context, PropertyPathTestingUtils.toPath(path, type, context)));
.getColumn(context.getAggregatePath(PersistentPropertyPathTestUtils.getPath(path, type, context)));
}
private PersistentPropertyPath<RelationalPersistentProperty> getPath(String path, Class<?> baseType) {
return PersistentPropertyPathTestUtils.getPath(context, path, baseType);
return PersistentPropertyPathTestUtils.getPath(path, baseType, context);
}
@SuppressWarnings("unused")

View File

@@ -15,17 +15,11 @@
*/
package org.springframework.data.jdbc.core.mapping;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.SoftAssertions.*;
import static org.springframework.data.relational.core.sql.SqlIdentifier.*;
import junit.framework.AssertionFailedError;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.relational.core.mapping.BasicRelationalPersistentProperty;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.MappedCollection;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
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 java.time.LocalDateTime;
import java.time.ZonedDateTime;
@@ -33,9 +27,16 @@ import java.util.Date;
import java.util.List;
import java.util.UUID;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.SoftAssertions.*;
import static org.springframework.data.relational.core.sql.SqlIdentifier.*;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.BasicRelationalPersistentProperty;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.MappedCollection;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
/**
* Unit tests for the {@link BasicRelationalPersistentProperty}.
@@ -63,9 +64,10 @@ public class BasicJdbcPersistentPropertyUnitTests {
String propertyName = "someList";
RelationalPersistentProperty listProperty = entity.getRequiredPersistentProperty(propertyName);
PersistentPropertyPathExtension path = getPersistentPropertyPath(DummyEntity.class, propertyName);
AggregatePath path = getPersistentPropertyPath(DummyEntity.class, propertyName);
assertThat(listProperty.getReverseColumnName(path)).isEqualTo(quoted("dummy_column_name"));
assertThat(listProperty.getReverseColumnName(path.getRequiredBaseProperty().getOwner()))
.isEqualTo(quoted("dummy_column_name"));
assertThat(listProperty.getKeyColumn()).isEqualTo(quoted("dummy_key_column_name"));
}
@@ -76,10 +78,11 @@ public class BasicJdbcPersistentPropertyUnitTests {
RelationalPersistentProperty listProperty = context //
.getRequiredPersistentEntity(WithCollections.class) //
.getRequiredPersistentProperty(propertyName);
PersistentPropertyPathExtension path = getPersistentPropertyPath(DummyEntity.class, propertyName);
AggregatePath path = getPersistentPropertyPath(DummyEntity.class, propertyName);
assertThat(listProperty.getKeyColumn()).isEqualTo(quoted("WITH_COLLECTIONS_KEY"));
assertThat(listProperty.getReverseColumnName(path)).isEqualTo(quoted("some_value"));
assertThat(listProperty.getReverseColumnName(path.getRequiredBaseProperty().getOwner()))
.isEqualTo(quoted("some_value"));
}
@Test // DATAJDBC-331
@@ -88,10 +91,11 @@ public class BasicJdbcPersistentPropertyUnitTests {
RelationalPersistentProperty listProperty = context //
.getRequiredPersistentEntity(WithCollections.class) //
.getRequiredPersistentProperty("overrideList");
PersistentPropertyPathExtension path = getPersistentPropertyPath(WithCollections.class, "overrideList");
AggregatePath path = getPersistentPropertyPath(WithCollections.class, "overrideList");
assertThat(listProperty.getKeyColumn()).isEqualTo(quoted("override_key"));
assertThat(listProperty.getReverseColumnName(path)).isEqualTo(quoted("override_id"));
assertThat(listProperty.getReverseColumnName(path.getRequiredBaseProperty().getOwner()))
.isEqualTo(quoted("override_id"));
}
@Test // GH-938
@@ -126,12 +130,13 @@ public class BasicJdbcPersistentPropertyUnitTests {
});
}
private PersistentPropertyPathExtension getPersistentPropertyPath(Class<?> type, String propertyName) {
private AggregatePath getPersistentPropertyPath(Class<?> type, String propertyName) {
PersistentPropertyPath<RelationalPersistentProperty> path = context
.findPersistentPropertyPaths(type, p -> p.getName().equals(propertyName)).getFirst()
.orElseThrow(() -> new AssertionFailedError(String.format("Couldn't find path for '%s'", propertyName)));
return new PersistentPropertyPathExtension(context, path);
return context.getAggregatePath(path);
}
@SuppressWarnings("unused")
@@ -142,8 +147,7 @@ public class BasicJdbcPersistentPropertyUnitTests {
@SuppressWarnings("unused")
private static class DummyEntity {
@Id
private final Long id;
@Id private final Long id;
private final SomeEnum someEnum;
private final LocalDateTime localDateTime;
private final ZonedDateTime zonedDateTime;
@@ -152,13 +156,13 @@ public class BasicJdbcPersistentPropertyUnitTests {
private final UUID uuid;
@MappedCollection(idColumn = "dummy_column_name",
keyColumn = "dummy_key_column_name")
private List<Integer> someList;
keyColumn = "dummy_key_column_name") private List<Integer> someList;
// DATACMNS-106
private @Column("dummy_name") String name;
private DummyEntity(Long id, SomeEnum someEnum, LocalDateTime localDateTime, ZonedDateTime zonedDateTime, AggregateReference<DummyEntity, Long> reference, List<String> listField, UUID uuid) {
private DummyEntity(Long id, SomeEnum someEnum, LocalDateTime localDateTime, ZonedDateTime zonedDateTime,
AggregateReference<DummyEntity, Long> reference, List<String> listField, UUID uuid) {
this.id = id;
this.someEnum = someEnum;
this.localDateTime = localDateTime;
@@ -224,8 +228,7 @@ public class BasicJdbcPersistentPropertyUnitTests {
private static class WithCollections {
@Column(value = "some_value")
List<Integer> someList;
@Column(value = "some_value") List<Integer> someList;
@Column(value = "some_value") //
@MappedCollection(idColumn = "override_id", keyColumn = "override_key") //

View File

@@ -1,40 +0,0 @@
/*
* Copyright 2018-2023 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.jdbc.core.mapping;
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
/**
* @author Jens Schauder
*/
public final class PersistentPropertyPathTestUtils {
private PersistentPropertyPathTestUtils() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
public static PersistentPropertyPath<RelationalPersistentProperty> getPath(RelationalMappingContext context,
String path, Class<?> baseType) {
return context.findPersistentPropertyPaths(baseType, p -> p.isEntity()) //
.filter(p -> p.toDotPath().equals(path)) //
.stream() //
.findFirst() //
.orElseThrow(() -> new IllegalArgumentException(String.format("No path for %s based on %s", path, baseType)));
}
}

View File

@@ -58,7 +58,7 @@ public class DefaultNamingStrategyUnitTests {
}
@Test // DATAJDBC-184
public void getReverseColumnName() {
public void getReverseColumnInfoName() {
assertThat(target.getReverseColumnName(persistentEntity.getPersistentProperty("dummySubEntities")))
.isEqualTo("dummy_entity");
}

View File

@@ -28,7 +28,7 @@ import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jdbc.core.PropertyPathTestingUtils;
import org.springframework.data.jdbc.core.PersistentPropertyPathTestUtils;
import org.springframework.data.jdbc.core.convert.Identifier;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.mapping.PersistentPropertyPath;
@@ -54,7 +54,7 @@ public class MyBatisDataAccessStrategyUnitTests {
MyBatisDataAccessStrategy accessStrategy = new MyBatisDataAccessStrategy(session, IdentifierProcessing.ANSI);
PersistentPropertyPath<RelationalPersistentProperty> path = PropertyPathTestingUtils.toPath("one.two",
PersistentPropertyPath<RelationalPersistentProperty> path = PersistentPropertyPathTestUtils.getPath("one.two",
DummyEntity.class, context);
@BeforeEach