Browse Source

Polishing.

Removed tests for circular references since they are not supported by Spring Data Relational.

Closes #1599
See #756, #1600
Original pull request #1629
pull/1685/head
Jens Schauder 2 years ago
parent
commit
5342e02b8d
No known key found for this signature in database
GPG Key ID: 14C72020B3B56291
  1. 8
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/DefaultSqlTypeMapping.java
  2. 10
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/ForeignKey.java
  3. 17
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriter.java
  4. 2
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/SchemaDiff.java
  5. 8
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/SqlTypeMapping.java
  6. 1
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/Table.java
  7. 1
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/TableDiff.java
  8. 96
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/Tables.java
  9. 1
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriterIntegrationTests.java
  10. 147
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriterUnitTests.java

8
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/DefaultSqlTypeMapping.java

@ -32,6 +32,8 @@ import org.springframework.util.ClassUtils; @@ -32,6 +32,8 @@ import org.springframework.util.ClassUtils;
* instance of a class implementing {@link SqlTypeMapping} interface can be set on the {@link Tables} class
*
* @author Kurt Niemi
* @author Evgenii Koba
* @author Jens Schauder
* @since 3.2
*/
public class DefaultSqlTypeMapping implements SqlTypeMapping {
@ -61,11 +63,11 @@ public class DefaultSqlTypeMapping implements SqlTypeMapping { @@ -61,11 +63,11 @@ public class DefaultSqlTypeMapping implements SqlTypeMapping {
@Override
public String getColumnType(RelationalPersistentProperty property) {
return typeMap.get(ClassUtils.resolvePrimitiveIfNecessary(property.getActualType()));
return getColumnType(property.getActualType());
}
@Override
public String getColumnTypeByClass(Class clazz) {
return typeMap.get(clazz);
public String getColumnType(Class<?> type) {
return typeMap.get(ClassUtils.resolvePrimitiveIfNecessary(type));
}
}

10
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/ForeignKey.java

@ -7,10 +7,10 @@ import java.util.Objects; @@ -7,10 +7,10 @@ import java.util.Objects;
* Models a Foreign Key for generating SQL for Schema generation.
*
* @author Evgenii Koba
* @since 3.2
* @since 3.3
*/
record ForeignKey(String name, String tableName, List<String> columnNames, String referencedTableName,
List<String> referencedColumnNames) {
List<String> referencedColumnNames) {
@Override
public boolean equals(Object o) {
if (this == o)
@ -18,9 +18,9 @@ record ForeignKey(String name, String tableName, List<String> columnNames, Strin @@ -18,9 +18,9 @@ record ForeignKey(String name, String tableName, List<String> columnNames, Strin
if (o == null || getClass() != o.getClass())
return false;
ForeignKey that = (ForeignKey) o;
return Objects.equals(tableName, that.tableName) && Objects.equals(columnNames, that.columnNames) && Objects.equals(
referencedTableName, that.referencedTableName) && Objects.equals(referencedColumnNames,
that.referencedColumnNames);
return Objects.equals(tableName, that.tableName) && Objects.equals(columnNames, that.columnNames)
&& Objects.equals(referencedTableName, that.referencedTableName)
&& Objects.equals(referencedColumnNames, that.referencedColumnNames);
}
@Override

17
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriter.java

@ -55,6 +55,7 @@ import java.util.Set; @@ -55,6 +55,7 @@ import java.util.Set;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.core.io.Resource;
import org.springframework.data.mapping.context.MappingContext;
@ -90,6 +91,7 @@ import org.springframework.util.Assert; @@ -90,6 +91,7 @@ import org.springframework.util.Assert;
*
* @author Kurt Niemi
* @author Mark Paluch
* @author Evgenii Koba
* @since 3.2
*/
public class LiquibaseChangeSetWriter {
@ -323,16 +325,18 @@ public class LiquibaseChangeSetWriter { @@ -323,16 +325,18 @@ public class LiquibaseChangeSetWriter {
private SchemaDiff initial() {
Tables mappedEntities = Tables.from(mappingContext.getPersistentEntities().stream().filter(schemaFilter),
sqlTypeMapping, null, mappingContext);
Stream<? extends RelationalPersistentEntity<?>> entities = mappingContext.getPersistentEntities().stream()
.filter(schemaFilter);
Tables mappedEntities = Tables.from(entities, sqlTypeMapping, null, mappingContext);
return SchemaDiff.diff(mappedEntities, Tables.empty(), nameComparator);
}
private SchemaDiff differenceOf(Database database) throws LiquibaseException {
Tables existingTables = getLiquibaseModel(database);
Tables mappedEntities = Tables.from(mappingContext.getPersistentEntities().stream().filter(schemaFilter),
sqlTypeMapping, database.getDefaultCatalogName(), mappingContext);
Stream<? extends RelationalPersistentEntity<?>> entities = mappingContext.getPersistentEntities().stream()
.filter(schemaFilter);
Tables mappedEntities = Tables.from(entities, sqlTypeMapping, database.getDefaultCatalogName(), mappingContext);
return SchemaDiff.diff(mappedEntities, existingTables, nameComparator);
}
@ -482,12 +486,15 @@ public class LiquibaseChangeSetWriter { @@ -482,12 +486,15 @@ public class LiquibaseChangeSetWriter {
private static List<ForeignKey> extractForeignKeys(liquibase.structure.core.Table table) {
return table.getOutgoingForeignKeys().stream().map(foreignKey -> {
String tableName = foreignKey.getForeignKeyTable().getName();
List<String> columnNames = foreignKey.getForeignKeyColumns().stream()
.map(liquibase.structure.core.Column::getName).toList();
String referencedTableName = foreignKey.getPrimaryKeyTable().getName();
List<String> referencedColumnNames = foreignKey.getPrimaryKeyColumns().stream()
.map(liquibase.structure.core.Column::getName).toList();
return new ForeignKey(foreignKey.getName(), tableName, columnNames, referencedTableName, referencedColumnNames);
}).collect(Collectors.toList());
}
@ -582,6 +589,7 @@ public class LiquibaseChangeSetWriter { @@ -582,6 +589,7 @@ public class LiquibaseChangeSetWriter {
change.setBaseColumnNames(String.join(",", foreignKey.columnNames()));
change.setReferencedTableName(foreignKey.referencedTableName());
change.setReferencedColumnNames(String.join(",", foreignKey.referencedColumnNames()));
return change;
}
@ -590,6 +598,7 @@ public class LiquibaseChangeSetWriter { @@ -590,6 +598,7 @@ public class LiquibaseChangeSetWriter {
DropForeignKeyConstraintChange change = new DropForeignKeyConstraintChange();
change.setConstraintName(foreignKey.name());
change.setBaseTableName(foreignKey.tableName());
return change;
}

2
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/SchemaDiff.java

@ -31,6 +31,7 @@ import java.util.function.Predicate; @@ -31,6 +31,7 @@ import java.util.function.Predicate;
* or delete)
*
* @author Kurt Niemi
* @author Evgenii Koba
* @since 3.2
*/
record SchemaDiff(List<Table> tableAdditions, List<Table> tableDeletions, List<TableDiff> tableDiffs) {
@ -120,6 +121,7 @@ record SchemaDiff(List<Table> tableAdditions, List<Table> tableDeletions, List<T @@ -120,6 +121,7 @@ record SchemaDiff(List<Table> tableAdditions, List<Table> tableDeletions, List<T
private static <T> Collection<T> findDiffs(Map<String, T> baseMapping, Map<String, T> toCompareMapping,
Comparator<String> nameComparator) {
Map<String, T> diff = new TreeMap<>(nameComparator);
diff.putAll(toCompareMapping);
baseMapping.keySet().forEach(diff::remove);

8
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/SqlTypeMapping.java

@ -25,6 +25,8 @@ import org.springframework.util.ObjectUtils; @@ -25,6 +25,8 @@ import org.springframework.util.ObjectUtils;
*
* @author Kurt Niemi
* @author Mark Paluch
* @author Evgenii Koba
* @author Jens Schauder
* @since 3.2
*/
@FunctionalInterface
@ -43,12 +45,14 @@ public interface SqlTypeMapping { @@ -43,12 +45,14 @@ public interface SqlTypeMapping {
/**
* Determines a column type for Class.
*
* @param clazz class for which the type should be determined.
* @param type class for which the type should be determined.
* @return the SQL type to use, such as {@code VARCHAR} or {@code NUMERIC}. Can be {@literal null} if the strategy
* cannot provide a column type.
*
* @since 3.3
*/
@Nullable
default String getColumnTypeByClass(Class clazz) {
default String getColumnType(Class<?> type) {
return null;
}

1
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/Table.java

@ -26,6 +26,7 @@ import org.springframework.util.ObjectUtils; @@ -26,6 +26,7 @@ import org.springframework.util.ObjectUtils;
* Models a Table for generating SQL for Schema generation.
*
* @author Kurt Niemi
* @author Evgenii Koba
* @since 3.2
*/
record Table(@Nullable String schema, String name, List<Column> columns, List<ForeignKey> foreignKeys) {

1
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/TableDiff.java

@ -23,6 +23,7 @@ import java.util.List; @@ -23,6 +23,7 @@ import java.util.List;
* target {@link Tables}.
*
* @author Kurt Niemi
* @author Evgenii Koba
* @since 3.2
*/
record TableDiff(Table table, List<Column> columnsToAdd, List<Column> columnsToDrop, List<ForeignKey> fkToAdd,

96
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/Tables.java

@ -26,6 +26,7 @@ import java.util.Optional; @@ -26,6 +26,7 @@ import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.data.annotation.Id;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.relational.core.mapping.MappedCollection;
@ -34,11 +35,13 @@ import org.springframework.data.relational.core.mapping.RelationalPersistentEnti @@ -34,11 +35,13 @@ import org.springframework.data.relational.core.mapping.RelationalPersistentEnti
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.data.relational.core.sql.SqlIdentifier;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Model class that contains Table/Column information that can be used to generate SQL for Schema generation.
*
* @author Kurt Niemi
* @author Evgenii Koba
* @since 3.2
*/
record Tables(List<Table> tables) {
@ -71,7 +74,7 @@ record Tables(List<Table> tables) { @@ -71,7 +74,7 @@ record Tables(List<Table> tables) {
}
Column column = new Column(property.getColumnName().getReference(), sqlTypeMapping.getColumnType(property),
sqlTypeMapping.isNullable(property), identifierColumns.contains(property));
sqlTypeMapping.isNullable(property), identifierColumns.contains(property));
table.columns().add(column);
}
return table;
@ -92,34 +95,40 @@ record Tables(List<Table> tables) { @@ -92,34 +95,40 @@ record Tables(List<Table> tables) {
private static void applyForeignKeyMetadata(List<Table> tables, List<ForeignKeyMetadata> foreignKeyMetadataList) {
foreignKeyMetadataList.forEach(foreignKeyMetadata -> {
Table table = tables.stream().filter(t -> t.name().equals(foreignKeyMetadata.tableName)).findAny().get();
Table table = tables.stream().filter(t -> t.name().equals(foreignKeyMetadata.tableName)).findAny().orElseThrow();
List<Column> parentIdColumns = collectParentIdentityColumns(foreignKeyMetadata, foreignKeyMetadataList, tables);
List<String> parentIdColumnNames = parentIdColumns.stream().map(Column::name).toList();
String foreignKeyName = getForeignKeyName(foreignKeyMetadata.parentTableName, parentIdColumnNames);
if(parentIdColumnNames.size() == 1) {
addIfAbsent(table.columns(), new Column(foreignKeyMetadata.referencingColumnName(), parentIdColumns.get(0).type(),
false, table.getIdColumns().isEmpty()));
if(foreignKeyMetadata.keyColumnName() != null) {
addIfAbsent(table.columns(), new Column(foreignKeyMetadata.keyColumnName(), foreignKeyMetadata.keyColumnType(),
false, true));
if (parentIdColumnNames.size() == 1) {
addIfAbsent(table.columns(), new Column(foreignKeyMetadata.referencingColumnName(),
parentIdColumns.get(0).type(), false, table.getIdColumns().isEmpty()));
if (foreignKeyMetadata.keyColumnName() != null) {
addIfAbsent(table.columns(),
new Column(foreignKeyMetadata.keyColumnName(), foreignKeyMetadata.keyColumnType(), false, true));
}
addIfAbsent(table.foreignKeys(), new ForeignKey(foreignKeyName, foreignKeyMetadata.tableName(),
List.of(foreignKeyMetadata.referencingColumnName()), foreignKeyMetadata.parentTableName(), parentIdColumnNames));
addIfAbsent(table.foreignKeys(),
new ForeignKey(foreignKeyName, foreignKeyMetadata.tableName(),
List.of(foreignKeyMetadata.referencingColumnName()), foreignKeyMetadata.parentTableName(),
parentIdColumnNames));
} else {
addIfAbsent(table.columns(), parentIdColumns.toArray(new Column[0]));
addIfAbsent(table.columns(), new Column(foreignKeyMetadata.keyColumnName(), foreignKeyMetadata.keyColumnType(),
false, true));
addIfAbsent(table.foreignKeys(), new ForeignKey(foreignKeyName, foreignKeyMetadata.tableName(), parentIdColumnNames,
foreignKeyMetadata.parentTableName(), parentIdColumnNames));
addIfAbsent(table.columns(),
new Column(foreignKeyMetadata.keyColumnName(), foreignKeyMetadata.keyColumnType(), false, true));
addIfAbsent(table.foreignKeys(), new ForeignKey(foreignKeyName, foreignKeyMetadata.tableName(),
parentIdColumnNames, foreignKeyMetadata.parentTableName(), parentIdColumnNames));
}
});
}
private static <E> void addIfAbsent(List<E> list, E... elements) {
for(E element : elements) {
private static <E> void addIfAbsent(List<E> list, E... elements) {
for (E element : elements) {
if (!list.contains(element)) {
list.add(element);
}
@ -137,26 +146,28 @@ record Tables(List<Table> tables) { @@ -137,26 +146,28 @@ record Tables(List<Table> tables) {
excludeTables.add(child.tableName());
Table parentTable = findTableByName(tables, child.parentTableName());
ForeignKeyMetadata parentMetadata = findMetadataByTableName(foreignKeyMetadataList, child.parentTableName(), excludeTables);
ForeignKeyMetadata parentMetadata = findMetadataByTableName(foreignKeyMetadataList, child.parentTableName(),
excludeTables);
List<Column> parentIdColumns = parentTable.getIdColumns();
if (!parentIdColumns.isEmpty()) {
return new ArrayList<>(parentIdColumns);
} else if(parentMetadata == null) {
//mustn't happen, probably wrong entity declaration
return new ArrayList<>();
} else {
List<Column> parentParentIdColumns = collectParentIdentityColumns(parentMetadata, foreignKeyMetadataList, tables);
if (parentParentIdColumns.size() == 1) {
Column parentParentIdColumn = parentParentIdColumns.get(0);
Column withChangedName = new Column(parentMetadata.referencingColumnName, parentParentIdColumn.type(), false, true);
parentParentIdColumns = new LinkedList<>(List.of(withChangedName));
}
if (parentMetadata.keyColumnName() != null) {
parentParentIdColumns.add(new Column(parentMetadata.keyColumnName(), parentMetadata.keyColumnType(), false, true));
}
return parentParentIdColumns;
}
Assert.state(parentMetadata != null, "parentMetadata must not be null at this stage");
List<Column> parentParentIdColumns = collectParentIdentityColumns(parentMetadata, foreignKeyMetadataList, tables);
if (parentParentIdColumns.size() == 1) {
Column parentParentIdColumn = parentParentIdColumns.get(0);
Column withChangedName = new Column(parentMetadata.referencingColumnName, parentParentIdColumn.type(), false,
true);
parentParentIdColumns = new LinkedList<>(List.of(withChangedName));
}
if (parentMetadata.keyColumnName() != null) {
parentParentIdColumns
.add(new Column(parentMetadata.keyColumnName(), parentMetadata.keyColumnType(), false, true));
}
return parentParentIdColumns;
}
@Nullable
@ -167,14 +178,13 @@ record Tables(List<Table> tables) { @@ -167,14 +178,13 @@ record Tables(List<Table> tables) {
@Nullable
private static ForeignKeyMetadata findMetadataByTableName(List<ForeignKeyMetadata> metadata, String tableName,
Set<String> excludeTables) {
return metadata.stream()
.filter(m -> m.tableName().equals(tableName) && !excludeTables.contains(m.parentTableName()))
.findAny()
.filter(m -> m.tableName().equals(tableName) && !excludeTables.contains(m.parentTableName())).findAny()
.orElse(null);
}
private static ForeignKeyMetadata createForeignKeyMetadata(
RelationalPersistentEntity<?> entity,
private static ForeignKeyMetadata createForeignKeyMetadata(RelationalPersistentEntity<?> entity,
RelationalPersistentProperty property,
MappingContext<? extends RelationalPersistentEntity<?>, ? extends RelationalPersistentProperty> context,
SqlTypeMapping sqlTypeMapping) {
@ -182,30 +192,26 @@ record Tables(List<Table> tables) { @@ -182,30 +192,26 @@ record Tables(List<Table> tables) {
RelationalPersistentEntity childEntity = context.getRequiredPersistentEntity(property.getActualType());
String referencedKeyColumnType = null;
if(property.isAnnotationPresent(MappedCollection.class)) {
if (property.isAnnotationPresent(MappedCollection.class)) {
if (property.getType() == List.class) {
referencedKeyColumnType = sqlTypeMapping.getColumnTypeByClass(Integer.class);
referencedKeyColumnType = sqlTypeMapping.getColumnType(Integer.class);
} else if (property.getType() == Map.class) {
referencedKeyColumnType = sqlTypeMapping.getColumnTypeByClass(property.getComponentType());
referencedKeyColumnType = sqlTypeMapping.getColumnType(property.getComponentType());
}
}
return new ForeignKeyMetadata(
childEntity.getTableName().getReference(),
return new ForeignKeyMetadata(childEntity.getTableName().getReference(),
property.getReverseColumnName(entity).getReference(),
Optional.ofNullable(property.getKeyColumn()).map(SqlIdentifier::getReference).orElse(null),
referencedKeyColumnType,
entity.getTableName().getReference()
);
referencedKeyColumnType, entity.getTableName().getReference());
}
//TODO should we place it in BasicRelationalPersistentProperty/BasicRelationalPersistentEntity and generate using NamingStrategy?
private static String getForeignKeyName(String referencedTableName, List<String> referencedColumnNames) {
return String.format("%s_%s_fk", referencedTableName, String.join("_", referencedColumnNames));
}
private record ForeignKeyMetadata(String tableName, String referencingColumnName, @Nullable String keyColumnName,
@Nullable String keyColumnType, String parentTableName) {
@Nullable String keyColumnType, String parentTableName) {
}
}

1
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriterIntegrationTests.java

@ -55,6 +55,7 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; @@ -55,6 +55,7 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
* Integration tests for {@link LiquibaseChangeSetWriter}.
*
* @author Mark Paluch
* @author Evgenii Koba
*/
class LiquibaseChangeSetWriterIntegrationTests {

147
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriterUnitTests.java

@ -15,15 +15,8 @@ @@ -15,15 +15,8 @@
*/
package org.springframework.data.jdbc.core.mapping.schema;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import static org.assertj.core.api.Assertions.*;
import java.util.stream.Collectors;
import liquibase.change.Change;
import liquibase.change.ColumnConfig;
import liquibase.change.core.AddForeignKeyConstraintChange;
@ -31,6 +24,12 @@ import liquibase.change.core.CreateTableChange; @@ -31,6 +24,12 @@ import liquibase.change.core.CreateTableChange;
import liquibase.changelog.ChangeSet;
import liquibase.changelog.DatabaseChangeLog;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import org.assertj.core.groups.Tuple;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
@ -39,12 +38,12 @@ import org.springframework.data.relational.core.mapping.Column; @@ -39,12 +38,12 @@ 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.util.Optionals;
/**
* Unit tests for {@link LiquibaseChangeSetWriter}.
*
* @author Mark Paluch
* @author Evgenii Koba
*/
class LiquibaseChangeSetWriterUnitTests {
@ -117,8 +116,8 @@ class LiquibaseChangeSetWriterUnitTests { @@ -117,8 +116,8 @@ class LiquibaseChangeSetWriterUnitTests {
ChangeSet changeSet = writer.createChangeSet(ChangeSetMetadata.create(), new DatabaseChangeLog());
Optional<Change> tableWithFk = changeSet.getChanges().stream().filter(change -> {
return change instanceof CreateTableChange && ((CreateTableChange) change).getTableName()
.equals("table_with_fk_field");
return change instanceof CreateTableChange
&& ((CreateTableChange) change).getTableName().equals("table_with_fk_field");
}).findFirst();
assertThat(tableWithFk.isPresent()).isEqualTo(true);
@ -136,23 +135,19 @@ class LiquibaseChangeSetWriterUnitTests { @@ -136,23 +135,19 @@ class LiquibaseChangeSetWriterUnitTests {
ChangeSet changeSet = writer.createChangeSet(ChangeSetMetadata.create(), new DatabaseChangeLog());
assertCreateTable(changeSet, "no_id_table",
Tuple.tuple("field", "VARCHAR(255 BYTE)", null),
Tuple.tuple("list_id", "INT", true),
Tuple.tuple("list_of_map_of_no_id_tables_key", "INT", true),
assertCreateTable(changeSet, "no_id_table", Tuple.tuple("field", "VARCHAR(255 BYTE)", null),
Tuple.tuple("list_id", "INT", true), Tuple.tuple("list_of_map_of_no_id_tables_key", "INT", true),
Tuple.tuple("map_of_no_id_tables_key", "VARCHAR(255 BYTE)", true));
assertCreateTable(changeSet, "map_of_no_id_tables",
Tuple.tuple("list_id", "INT", true),
assertCreateTable(changeSet, "map_of_no_id_tables", Tuple.tuple("list_id", "INT", true),
Tuple.tuple("list_of_map_of_no_id_tables_key", "INT", true));
assertCreateTable(changeSet, "list_of_map_of_no_id_tables", Tuple.tuple("id", "INT", true));
assertAddForeignKey(changeSet, "no_id_table", "list_id,list_of_map_of_no_id_tables_key",
"map_of_no_id_tables", "list_id,list_of_map_of_no_id_tables_key");
assertAddForeignKey(changeSet, "no_id_table", "list_id,list_of_map_of_no_id_tables_key", "map_of_no_id_tables",
"list_id,list_of_map_of_no_id_tables_key");
assertAddForeignKey(changeSet, "map_of_no_id_tables", "list_id",
"list_of_map_of_no_id_tables", "id");
assertAddForeignKey(changeSet, "map_of_no_id_tables", "list_id", "list_of_map_of_no_id_tables", "id");
}
@Test // GH-1599
@ -165,76 +160,25 @@ class LiquibaseChangeSetWriterUnitTests { @@ -165,76 +160,25 @@ class LiquibaseChangeSetWriterUnitTests {
ChangeSet changeSet = writer.createChangeSet(ChangeSetMetadata.create(), new DatabaseChangeLog());
assertCreateTable(changeSet, "other_table",
Tuple.tuple("id", "BIGINT", true), Tuple.tuple("one_to_one_level1", "INT", null));
assertCreateTable(changeSet, "other_table", Tuple.tuple("id", "BIGINT", true),
Tuple.tuple("one_to_one_level1", "INT", null));
assertCreateTable(changeSet, "one_to_one_level2", Tuple.tuple("one_to_one_level1", "INT", true));
assertCreateTable(changeSet, "no_id_table", Tuple.tuple("field", "VARCHAR(255 BYTE)", null),
Tuple.tuple("one_to_one_level2", "INT", true), Tuple.tuple("additional_one_to_one_level2", "INT", null));
assertAddForeignKey(changeSet, "other_table", "one_to_one_level1",
"one_to_one_level1", "id");
assertAddForeignKey(changeSet, "other_table", "one_to_one_level1", "one_to_one_level1", "id");
assertAddForeignKey(changeSet, "one_to_one_level2", "one_to_one_level1",
"one_to_one_level1", "id");
assertAddForeignKey(changeSet, "one_to_one_level2", "one_to_one_level1", "one_to_one_level1", "id");
assertAddForeignKey(changeSet, "no_id_table", "one_to_one_level2",
"one_to_one_level2", "one_to_one_level1");
assertAddForeignKey(changeSet, "no_id_table", "one_to_one_level2", "one_to_one_level2", "one_to_one_level1");
assertAddForeignKey(changeSet, "no_id_table", "additional_one_to_one_level2",
"one_to_one_level2", "one_to_one_level1");
assertAddForeignKey(changeSet, "no_id_table", "additional_one_to_one_level2", "one_to_one_level2",
"one_to_one_level1");
}
@Test // GH-1599
void createForeignKeyForCircularWithId() {
RelationalMappingContext context = new RelationalMappingContext() {
@Override
public Collection<RelationalPersistentEntity<?>> getPersistentEntities() {
return List.of(getPersistentEntity(CircularWithId.class), getPersistentEntity(ParentOfCircularWithId.class));
}
};
LiquibaseChangeSetWriter writer = new LiquibaseChangeSetWriter(context);
ChangeSet changeSet = writer.createChangeSet(ChangeSetMetadata.create(), new DatabaseChangeLog());
assertCreateTable(changeSet, "circular_with_id",
Tuple.tuple("id", "INT", true),
Tuple.tuple("circular_with_id", "INT", null),
Tuple.tuple("parent_of_circular_with_id", "INT", null));
assertAddForeignKey(changeSet, "circular_with_id", "parent_of_circular_with_id",
"parent_of_circular_with_id", "id");
assertAddForeignKey(changeSet, "circular_with_id", "circular_with_id",
"circular_with_id", "id");
}
@Test // GH-1599
void createForeignKeyForCircularNoId() {
RelationalMappingContext context = new RelationalMappingContext() {
@Override
public Collection<RelationalPersistentEntity<?>> getPersistentEntities() {
return List.of(getPersistentEntity(CircularNoId.class), getPersistentEntity(ParentOfCircularNoId.class));
}
};
LiquibaseChangeSetWriter writer = new LiquibaseChangeSetWriter(context);
ChangeSet changeSet = writer.createChangeSet(ChangeSetMetadata.create(), new DatabaseChangeLog());
assertCreateTable(changeSet, "circular_no_id",
Tuple.tuple("circular_no_id", "INT", true),
Tuple.tuple("parent_of_circular_no_id", "INT", null));
assertAddForeignKey(changeSet, "circular_no_id", "parent_of_circular_no_id",
"parent_of_circular_no_id", "id");
assertAddForeignKey(changeSet, "circular_no_id", "circular_no_id",
"circular_no_id", "parent_of_circular_no_id");
}
void assertCreateTable(ChangeSet changeSet, String tableName, Tuple... columnTuples) {
Optional<Change> createTableOptional = changeSet.getChanges().stream().filter(change -> {
@ -247,8 +191,8 @@ class LiquibaseChangeSetWriterUnitTests { @@ -247,8 +191,8 @@ class LiquibaseChangeSetWriterUnitTests {
.containsExactly(columnTuples);
}
void assertAddForeignKey(ChangeSet changeSet, String baseTableName, String baseColumnNames, String referencedTableName,
String referencedColumnNames) {
void assertAddForeignKey(ChangeSet changeSet, String baseTableName, String baseColumnNames,
String referencedTableName, String referencedColumnNames) {
Optional<Change> addFkOptional = changeSet.getChanges().stream().filter(change -> {
return change instanceof AddForeignKeyConstraintChange
&& ((AddForeignKeyConstraintChange) change).getBaseTableName().equals(baseTableName)
@ -280,22 +224,19 @@ class LiquibaseChangeSetWriterUnitTests { @@ -280,22 +224,19 @@ class LiquibaseChangeSetWriterUnitTests {
@org.springframework.data.relational.core.mapping.Table
static class Tables {
@Id int id;
@MappedCollection
Set<OtherTable> tables;
@MappedCollection Set<OtherTable> tables;
}
@org.springframework.data.relational.core.mapping.Table
static class SetOfTables {
@Id int id;
@MappedCollection(idColumn = "set_id")
Set<Tables> setOfTables;
@MappedCollection(idColumn = "set_id") Set<Tables> setOfTables;
}
@org.springframework.data.relational.core.mapping.Table
static class DifferentTables {
@Id int id;
@MappedCollection(idColumn = "tables_id")
Set<TableWithFkField> tables;
@MappedCollection(idColumn = "tables_id") Set<TableWithFkField> tables;
}
@org.springframework.data.relational.core.mapping.Table
@ -311,15 +252,13 @@ class LiquibaseChangeSetWriterUnitTests { @@ -311,15 +252,13 @@ class LiquibaseChangeSetWriterUnitTests {
@org.springframework.data.relational.core.mapping.Table
static class MapOfNoIdTables {
@MappedCollection
Map<String, NoIdTable> tables;
@MappedCollection Map<String, NoIdTable> tables;
}
@org.springframework.data.relational.core.mapping.Table
static class ListOfMapOfNoIdTables {
@Id int id;
@MappedCollection(idColumn = "list_id")
List<MapOfNoIdTables> listOfTables;
@MappedCollection(idColumn = "list_id") List<MapOfNoIdTables> listOfTables;
}
@org.springframework.data.relational.core.mapping.Table
@ -332,33 +271,7 @@ class LiquibaseChangeSetWriterUnitTests { @@ -332,33 +271,7 @@ class LiquibaseChangeSetWriterUnitTests {
@org.springframework.data.relational.core.mapping.Table
static class OneToOneLevel2 {
NoIdTable table1;
@Column("additional_one_to_one_level2")
NoIdTable table2;
}
@org.springframework.data.relational.core.mapping.Table
static class ParentOfCircularWithId {
@Id int id;
CircularWithId circularWithId;
}
@org.springframework.data.relational.core.mapping.Table
static class CircularWithId {
@Id int id;
CircularWithId circularWithId;
}
@org.springframework.data.relational.core.mapping.Table
static class ParentOfCircularNoId {
@Id int id;
CircularNoId CircularNoId;
}
@org.springframework.data.relational.core.mapping.Table
static class CircularNoId {
CircularNoId CircularNoId;
@Column("additional_one_to_one_level2") NoIdTable table2;
}
}

Loading…
Cancel
Save