From 5342e02b8dcb9565747fbe0c15d1f079fee39484 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Fri, 24 Nov 2023 11:40:52 +0100 Subject: [PATCH] Polishing. Removed tests for circular references since they are not supported by Spring Data Relational. Closes #1599 See #756, #1600 Original pull request #1629 --- .../mapping/schema/DefaultSqlTypeMapping.java | 8 +- .../jdbc/core/mapping/schema/ForeignKey.java | 10 +- .../schema/LiquibaseChangeSetWriter.java | 17 +- .../jdbc/core/mapping/schema/SchemaDiff.java | 2 + .../core/mapping/schema/SqlTypeMapping.java | 8 +- .../data/jdbc/core/mapping/schema/Table.java | 1 + .../jdbc/core/mapping/schema/TableDiff.java | 1 + .../data/jdbc/core/mapping/schema/Tables.java | 96 ++++++------ ...uibaseChangeSetWriterIntegrationTests.java | 1 + .../LiquibaseChangeSetWriterUnitTests.java | 147 ++++-------------- 10 files changed, 115 insertions(+), 176 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/DefaultSqlTypeMapping.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/DefaultSqlTypeMapping.java index cda9811f51..2d0a4a52c3 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/DefaultSqlTypeMapping.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/DefaultSqlTypeMapping.java @@ -32,6 +32,8 @@ * 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 DefaultSqlTypeMapping() { @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)); } } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/ForeignKey.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/ForeignKey.java index 638c78ddac..35e65dd85e 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/ForeignKey.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/ForeignKey.java @@ -7,10 +7,10 @@ * 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 columnNames, String referencedTableName, - List referencedColumnNames) { + List referencedColumnNames) { @Override public boolean equals(Object o) { if (this == o) @@ -18,9 +18,9 @@ public boolean equals(Object o) { 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 diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriter.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriter.java index d835c4f186..083ad71b84 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriter.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriter.java @@ -55,6 +55,7 @@ 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 @@ * * @author Kurt Niemi * @author Mark Paluch + * @author Evgenii Koba * @since 3.2 */ public class LiquibaseChangeSetWriter { @@ -323,16 +325,18 @@ private ChangeSet createChangeSet(ChangeSetMetadata metadata, SchemaDiff differe private SchemaDiff initial() { - Tables mappedEntities = Tables.from(mappingContext.getPersistentEntities().stream().filter(schemaFilter), - sqlTypeMapping, null, mappingContext); + Stream> 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> 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 @@ private Tables getLiquibaseModel(Database targetDatabase) throws LiquibaseExcept private static List extractForeignKeys(liquibase.structure.core.Table table) { return table.getOutgoingForeignKeys().stream().map(foreignKey -> { + String tableName = foreignKey.getForeignKeyTable().getName(); List columnNames = foreignKey.getForeignKeyColumns().stream() .map(liquibase.structure.core.Column::getName).toList(); + String referencedTableName = foreignKey.getPrimaryKeyTable().getName(); List 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 @@ private static AddForeignKeyConstraintChange addForeignKey(ForeignKey foreignKey change.setBaseColumnNames(String.join(",", foreignKey.columnNames())); change.setReferencedTableName(foreignKey.referencedTableName()); change.setReferencedColumnNames(String.join(",", foreignKey.referencedColumnNames())); + return change; } @@ -590,6 +598,7 @@ private static DropForeignKeyConstraintChange dropForeignKey(ForeignKey foreignK DropForeignKeyConstraintChange change = new DropForeignKeyConstraintChange(); change.setConstraintName(foreignKey.name()); change.setBaseTableName(foreignKey.tableName()); + return change; } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/SchemaDiff.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/SchemaDiff.java index ffa7032af5..b799865d26 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/SchemaDiff.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/SchemaDiff.java @@ -31,6 +31,7 @@ * or delete) * * @author Kurt Niemi + * @author Evgenii Koba * @since 3.2 */ record SchemaDiff(List tableAdditions, List
tableDeletions, List tableDiffs) { @@ -120,6 +121,7 @@ private static List diffTable(Tables mappedEntities, Map Collection findDiffs(Map baseMapping, Map toCompareMapping, Comparator nameComparator) { + Map diff = new TreeMap<>(nameComparator); diff.putAll(toCompareMapping); baseMapping.keySet().forEach(diff::remove); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/SqlTypeMapping.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/SqlTypeMapping.java index 982d739945..9af2226fdd 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/SqlTypeMapping.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/SqlTypeMapping.java @@ -25,6 +25,8 @@ * * @author Kurt Niemi * @author Mark Paluch + * @author Evgenii Koba + * @author Jens Schauder * @since 3.2 */ @FunctionalInterface @@ -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; } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/Table.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/Table.java index 908d87be9a..1ea14d377b 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/Table.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/Table.java @@ -26,6 +26,7 @@ * 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 columns, List foreignKeys) { diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/TableDiff.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/TableDiff.java index 189a9edd9d..c20f2c1d80 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/TableDiff.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/TableDiff.java @@ -23,6 +23,7 @@ * target {@link Tables}. * * @author Kurt Niemi + * @author Evgenii Koba * @since 3.2 */ record TableDiff(Table table, List columnsToAdd, List columnsToDrop, List fkToAdd, diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/Tables.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/Tables.java index 2a9421d49a..2c9f14c5fd 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/Tables.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/mapping/schema/Tables.java @@ -26,6 +26,7 @@ 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.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
tables) { @@ -71,7 +74,7 @@ public static Tables from(Stream> persis } 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 @@ public static Tables empty() { private static void applyForeignKeyMetadata(List
tables, List 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 parentIdColumns = collectParentIdentityColumns(foreignKeyMetadata, foreignKeyMetadataList, tables); List 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 void addIfAbsent(List list, E... elements) { - for(E element : elements) { + private static void addIfAbsent(List list, E... elements) { + + for (E element : elements) { if (!list.contains(element)) { list.add(element); } @@ -137,26 +146,28 @@ private static List collectParentIdentityColumns(ForeignKeyMetadata chil 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 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 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 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 @@ private static Table findTableByName(List
tables, String tableName) { @Nullable private static ForeignKeyMetadata findMetadataByTableName(List metadata, String tableName, Set 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 RelationalPersistentProperty> context, SqlTypeMapping sqlTypeMapping) { @@ -182,30 +192,26 @@ private static ForeignKeyMetadata createForeignKeyMetadata( 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 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) { } } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriterIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriterIntegrationTests.java index 805cf85256..1cbeac9c32 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriterIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriterIntegrationTests.java @@ -55,6 +55,7 @@ * Integration tests for {@link LiquibaseChangeSetWriter}. * * @author Mark Paluch + * @author Evgenii Koba */ class LiquibaseChangeSetWriterIntegrationTests { diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriterUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriterUnitTests.java index 3329dd0f2c..2681446c32 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriterUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/schema/LiquibaseChangeSetWriterUnitTests.java @@ -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.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.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 @@ void fieldForFkShouldNotBeCreatedTwice() { ChangeSet changeSet = writer.createChangeSet(ChangeSetMetadata.create(), new DatabaseChangeLog()); Optional 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 @@ void createForeignKeyForNestedEntities() { 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 @@ void createForeignKeyForOneToOneWithMultipleChildren() { 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> 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> 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 createTableOptional = changeSet.getChanges().stream().filter(change -> { @@ -247,8 +191,8 @@ void assertCreateTable(ChangeSet changeSet, String tableName, Tuple... columnTup .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 addFkOptional = changeSet.getChanges().stream().filter(change -> { return change instanceof AddForeignKeyConstraintChange && ((AddForeignKeyConstraintChange) change).getBaseTableName().equals(baseTableName) @@ -280,22 +224,19 @@ static class OtherTable { @org.springframework.data.relational.core.mapping.Table static class Tables { @Id int id; - @MappedCollection - Set tables; + @MappedCollection Set tables; } @org.springframework.data.relational.core.mapping.Table static class SetOfTables { @Id int id; - @MappedCollection(idColumn = "set_id") - Set setOfTables; + @MappedCollection(idColumn = "set_id") Set setOfTables; } @org.springframework.data.relational.core.mapping.Table static class DifferentTables { @Id int id; - @MappedCollection(idColumn = "tables_id") - Set tables; + @MappedCollection(idColumn = "tables_id") Set tables; } @org.springframework.data.relational.core.mapping.Table @@ -311,15 +252,13 @@ static class NoIdTable { @org.springframework.data.relational.core.mapping.Table static class MapOfNoIdTables { - @MappedCollection - Map tables; + @MappedCollection Map tables; } @org.springframework.data.relational.core.mapping.Table static class ListOfMapOfNoIdTables { @Id int id; - @MappedCollection(idColumn = "list_id") - List listOfTables; + @MappedCollection(idColumn = "list_id") List listOfTables; } @org.springframework.data.relational.core.mapping.Table @@ -332,33 +271,7 @@ static class OneToOneLevel1 { @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; } }