diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/BasicJdbcPersistentPropertyUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/BasicJdbcPersistentPropertyUnitTests.java index 5b631d680..c1e08cf95 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/BasicJdbcPersistentPropertyUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/BasicJdbcPersistentPropertyUnitTests.java @@ -15,7 +15,7 @@ */ package org.springframework.data.jdbc.core.mapping; -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; import lombok.Data; @@ -27,6 +27,7 @@ import java.util.UUID; import org.assertj.core.api.SoftAssertions; import org.junit.Test; + import org.springframework.data.annotation.Id; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.relational.core.mapping.BasicRelationalPersistentProperty; @@ -42,6 +43,7 @@ import org.springframework.data.relational.core.mapping.RelationalPersistentProp * @author Jens Schauder * @author Oliver Gierke * @author Florian Lüdiger + * @author Mark Paluch */ public class BasicJdbcPersistentPropertyUnitTests { @@ -51,8 +53,6 @@ public class BasicJdbcPersistentPropertyUnitTests { @Test // DATAJDBC-104 public void enumGetsStoredAsString() { - RelationalPersistentEntity persistentEntity = context.getRequiredPersistentEntity(DummyEntity.class); - entity.doWithProperties((PropertyHandler) p -> { switch (p.getName()) { case "someEnum": @@ -118,6 +118,28 @@ public class BasicJdbcPersistentPropertyUnitTests { softly.assertAll(); } + @Test // DATAJDBC-331 + public void detectsKeyColumnNameFromColumnAnnotation() { + + RelationalPersistentProperty listProperty = context // + .getRequiredPersistentEntity(WithCollections.class) // + .getRequiredPersistentProperty("someList"); + + assertThat(listProperty.getKeyColumn()).isEqualTo("some_key"); + assertThat(listProperty.getReverseColumnName()).isEqualTo("some_value"); + } + + @Test // DATAJDBC-331 + public void detectsKeyColumnOverrideNameFromMappedCollectionAnnotation() { + + RelationalPersistentProperty listProperty = context // + .getRequiredPersistentEntity(WithCollections.class) // + .getRequiredPersistentProperty("overrideList"); + + assertThat(listProperty.getKeyColumn()).isEqualTo("override_key"); + assertThat(listProperty.getReverseColumnName()).isEqualTo("override_id"); + } + private void checkTargetType(SoftAssertions softly, RelationalPersistentEntity persistentEntity, String propertyName, Class expected) { @@ -138,7 +160,8 @@ public class BasicJdbcPersistentPropertyUnitTests { private final List listField; private final UUID uuid; - @MappedCollection(idColumn = "dummy_column_name", keyColumn = "dummy_key_column_name") private List someList; + @MappedCollection(idColumn = "dummy_column_name", + keyColumn = "dummy_key_column_name") private List someList; // DATACMNS-106 private @Column("dummy_name") String name; @@ -157,6 +180,14 @@ public class BasicJdbcPersistentPropertyUnitTests { } } + @Data + private static class WithCollections { + + @Column(value = "some_value", keyColumn = "some_key") List someList; + @Column(value = "some_value", keyColumn = "some_key") @MappedCollection(idColumn = "override_id", + keyColumn = "override_key") List overrideList; + } + @SuppressWarnings("unused") private enum SomeEnum { ALPHA diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentProperty.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentProperty.java index 91e3b5f13..001f7fb3c 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentProperty.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/BasicRelationalPersistentProperty.java @@ -21,10 +21,8 @@ import java.time.temporal.Temporal; import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.stream.Stream; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.PersistentEntity; @@ -32,6 +30,7 @@ import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty; import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.Lazy; +import org.springframework.data.util.Optionals; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -88,41 +87,19 @@ public class BasicRelationalPersistentProperty extends AnnotationBasedPersistent .map(Embedded::value) // .orElse("")); - this.columnName = Lazy.of(() -> Optional.ofNullable( // - findAnnotation(Column.class)) // + this.columnName = Lazy.of(() -> Optional.ofNullable(findAnnotation(Column.class)) // .map(Column::value) // - .filter(StringUtils::hasText)// - ); - - this.collectionIdColumnName = Lazy.of(() -> - Stream.concat( // - Stream.of( // - findAnnotation(MappedCollection.class)) // - .filter(Objects::nonNull) // - .map(MappedCollection::idColumn), // - Stream.of( // - findAnnotation(Column.class)) // - .filter(Objects::nonNull) // - .map(Column::value) // - ) - .filter(StringUtils::hasText) - .findFirst() - ); - - this.collectionKeyColumnName = Lazy.of(() -> - Stream.concat( // - Stream.of( // - findAnnotation(MappedCollection.class)) // - .filter(Objects::nonNull) // - .map(MappedCollection::keyColumn), // - Stream.of( // - findAnnotation(Column.class)) // - .filter(Objects::nonNull) // - .map(Column::keyColumn) // - ) - .filter(StringUtils::hasText) - .findFirst() - ); + .filter(StringUtils::hasText)); + + this.collectionIdColumnName = Lazy.of(() -> Optionals + .toStream(Optional.ofNullable(findAnnotation(MappedCollection.class)).map(MappedCollection::idColumn), + Optional.ofNullable(findAnnotation(Column.class)).map(Column::value)) // + .filter(StringUtils::hasText).findFirst()); + + this.collectionKeyColumnName = Lazy.of(() -> Optionals + .toStream(Optional.ofNullable(findAnnotation(MappedCollection.class)).map(MappedCollection::keyColumn), + Optional.ofNullable(findAnnotation(Column.class)).map(Column::keyColumn)) // + .filter(StringUtils::hasText).findFirst()); } /* diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/MappedCollection.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/MappedCollection.java index 1df6a893b..971c40b6f 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/MappedCollection.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/MappedCollection.java @@ -20,12 +20,15 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.util.List; +import java.util.Map; /** - * The annotation to configure the mapping from an collection in the database. + * The annotation to configure the mapping for a {@link List} or {@link Map} property in the database. * * @since 1.1 * @author Bastian Wilhelm + * @author Mark Paluch */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE }) @@ -33,16 +36,18 @@ import java.lang.annotation.Target; public @interface MappedCollection { /** - * The column name for id column in the corresponding relationship table. - * If the default value (empty String) is used, the column name is resolved by the used - * {@link NamingStrategy} method {@link NamingStrategy#getReverseColumnName(RelationalPersistentProperty)} + * The column name for id column in the corresponding relationship table. Defaults to {@link NamingStrategy} usage if + * the value is empty. + * + * @see NamingStrategy#getReverseColumnName(RelationalPersistentProperty) */ String idColumn() default ""; /** - * The column name for key columns of List or Map collections in the corresponding relationship table. - * If the default value (empty String) is used, the column name is resolved by the used - * {@link NamingStrategy} method {@link NamingStrategy#getKeyColumn(RelationalPersistentProperty)} + * The column name for key columns of {@link List} or {@link Map} collections in the corresponding relationship table. + * Defaults to {@link NamingStrategy} usage if the value is empty. + * + * @see NamingStrategy#getKeyColumn(RelationalPersistentProperty) */ String keyColumn() default ""; } diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index 84d7eba35..54ed9fd18 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -1,5 +1,5 @@ = Spring Data JDBC - Reference Documentation -Jens Schauder, Jay Bryant, Mark Paluch +Jens Schauder, Jay Bryant, Mark Paluch, Bastian Wilhelm :revnumber: {version} :revdate: {localdate} :javadoc-base: https://docs.spring.io/spring-data/jdbc/docs/{revnumber}/api/