From 13cc4f6dd6f71ae9253fcd57ae6d2c3132bfe301 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Thu, 24 Jan 2019 11:25:38 +0100 Subject: [PATCH] DATAJDBC-111 - Polishing. Formatting. Removed some redundant tests. Some code simplifications. Original pull request: #110. --- .../jdbc/core/DefaultDataAccessStrategy.java | 8 +- .../data/jdbc/core/EntityRowMapper.java | 23 +- .../data/jdbc/core/SqlGenerator.java | 22 +- .../jdbc/core/EntityRowMapperUnitTests.java | 1 + ...qlGeneratorEmbeddedCascadingUnitTests.java | 188 ------------- .../core/SqlGeneratorEmbeddedUnitTests.java | 57 +++- ...toryEmbeddedCascadingIntegrationTests.java | 262 ------------------ ...toryEmbeddedImmutableIntegrationTests.java | 125 +-------- ...dbcRepositoryEmbeddedIntegrationTests.java | 74 +++-- ...dedNotInAggregateRootIntegrationTests.java | 2 +- ...mbeddedWithCollectionIntegrationTests.java | 2 +- ...EmbeddedWithReferenceIntegrationTests.java | 2 +- .../container-license-acceptance.txt | 1 + ...EmbeddedCascadingIntegrationTests-hsql.sql | 1 - ...eddedCascadingIntegrationTests-mariadb.sql | 1 - ...mbeddedCascadingIntegrationTests-mssql.sql | 2 - ...mbeddedCascadingIntegrationTests-mysql.sql | 1 - ...ddedCascadingIntegrationTests-postgres.sql | 2 - ...epositoryEmbeddedIntegrationTests-hsql.sql | 2 +- ...sitoryEmbeddedIntegrationTests-mariadb.sql | 2 +- ...positoryEmbeddedIntegrationTests-mssql.sql | 2 +- ...positoryEmbeddedIntegrationTests-mysql.sql | 2 +- ...itoryEmbeddedIntegrationTests-postgres.sql | 2 +- .../core/conversion/WritingContext.java | 83 +++--- .../BasicRelationalPersistentProperty.java | 27 +- .../relational/core/mapping/Embedded.java | 15 + .../mapping/RelationalPersistentProperty.java | 8 +- ...RelationalPersistentPropertyUnitTests.java | 35 ++- src/main/asciidoc/jdbc.adoc | 6 +- 29 files changed, 228 insertions(+), 730 deletions(-) delete mode 100644 spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/SqlGeneratorEmbeddedCascadingUnitTests.java delete mode 100644 spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedCascadingIntegrationTests.java create mode 100644 spring-data-jdbc/src/test/resources/container-license-acceptance.txt delete mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-hsql.sql delete mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-mariadb.sql delete mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-mssql.sql delete mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-mysql.sql delete mode 100644 spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-postgres.sql diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/DefaultDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/DefaultDataAccessStrategy.java index b04f73a7..fa11851f 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/DefaultDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/DefaultDataAccessStrategy.java @@ -293,11 +293,13 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy { } if(property.isEmbedded()){ - T value = (T) propertyAccessor.getProperty(property); - final RelationalPersistentEntity embeddedEntity = (RelationalPersistentEntity) context.getPersistentEntity(property.getType()); - final MapSqlParameterSource additionalParameters = getPropertyMap(value, embeddedEntity, prefix + property.getEmbeddedPrefix()); + + Object value = propertyAccessor.getProperty(property); + final RelationalPersistentEntity embeddedEntity = context.getPersistentEntity(property.getType()); + final MapSqlParameterSource additionalParameters = getPropertyMap((T)value, (RelationalPersistentEntity) embeddedEntity, prefix + property.getEmbeddedPrefix()); parameters.addValues(additionalParameters.getValues()); } else { + Object value = propertyAccessor.getProperty(property); Object convertedValue = converter.writeValue(value, ClassTypeInformation.from(property.getColumnType())); parameters.addValue(prefix + property.getColumnName(), convertedValue, JdbcUtil.sqlTypeFor(property.getColumnType())); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/EntityRowMapper.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/EntityRowMapper.java index 6af10051..0e29305f 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/EntityRowMapper.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/EntityRowMapper.java @@ -21,6 +21,7 @@ import java.util.Map; import org.springframework.core.convert.converter.Converter; import org.springframework.data.mapping.MappingException; +import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.PreferredConstructor; import org.springframework.data.relational.core.conversion.RelationalConverter; @@ -113,7 +114,7 @@ public class EntityRowMapper implements RowMapper { return accessStrategy.findAllByProperty(id, property); } else if (property.isMap() && id != null) { return ITERABLE_OF_ENTRY_TO_MAP_CONVERTER.convert(accessStrategy.findAllByProperty(id, property)); - } else if(property.isEmbedded()) { + } else if (property.isEmbedded()) { return readEmbeddedEntityFrom(resultSet, id, property, prefix); } else { return readFrom(resultSet, property, prefix); @@ -130,8 +131,9 @@ public class EntityRowMapper implements RowMapper { */ @Nullable private Object readFrom(ResultSet resultSet, RelationalPersistentProperty property, String prefix) { + if (property.isEntity()) { - return readEntityFrom(resultSet, property, prefix); + return readEntityFrom(resultSet, property, prefix); } Object value = getObjectFromResultSet(resultSet, prefix + property.getColumnName()); @@ -139,17 +141,18 @@ public class EntityRowMapper implements RowMapper { } - @Nullable - private S readEmbeddedEntityFrom(ResultSet rs, @Nullable Object id, RelationalPersistentProperty property, String prefix) { + private Object readEmbeddedEntityFrom(ResultSet rs, @Nullable Object id, RelationalPersistentProperty property, + String prefix) { + String newPrefix = prefix + property.getEmbeddedPrefix(); + RelationalPersistentEntity entity = context.getRequiredPersistentEntity(property.getActualType()); + + Object instance = createInstance(entity, rs, null, newPrefix); + @SuppressWarnings("unchecked") - RelationalPersistentEntity entity = (RelationalPersistentEntity) context - .getRequiredPersistentEntity(property.getActualType()); - - S instance = createInstance(entity, rs, null, newPrefix); - - PersistentPropertyAccessor accessor = converter.getPropertyAccessor(entity, instance); + PersistentPropertyAccessor accessor = converter.getPropertyAccessor((PersistentEntity) entity, + instance); for (RelationalPersistentProperty p : entity) { accessor.setProperty(p, readOrLoadProperty(rs, id, p, newPrefix)); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java index defdc2b1..3dbadfcc 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java @@ -72,7 +72,9 @@ class SqlGenerator { } private void initColumnNames(RelationalPersistentEntity entity, String prefix) { + entity.doWithProperties((PropertyHandler) property -> { + // the referencing column of referenced entity is expected to be on the other side of the relation if (!property.isEntity()) { initSimpleColumnName(property, prefix); @@ -83,16 +85,21 @@ class SqlGenerator { } private void initSimpleColumnName(RelationalPersistentProperty property, String prefix) { + String columnName = prefix + property.getColumnName(); + columnNames.add(columnName); + if (!entity.isIdProperty(property)) { nonIdColumnNames.add(columnName); } } private void initEmbeddedColumnNames(RelationalPersistentProperty property, String prefix) { + final String embeddedPrefix = property.getEmbeddedPrefix(); - final RelationalPersistentEntity embeddedEntity = context.getPersistentEntity(property.getColumnType()); + + final RelationalPersistentEntity embeddedEntity = context.getRequiredPersistentEntity(property.getColumnType()); initColumnNames(embeddedEntity, prefix + embeddedPrefix); } @@ -189,10 +196,10 @@ class SqlGenerator { } /** - * Adds the columns to the provided {@link SelectBuilder} representing simplem properties, including those from + * Adds the columns to the provided {@link SelectBuilder} representing simple properties, including those from * one-to-one relationships. * - * @param rootEntity + * @param rootEntity the root entity for which to add the columns. * @param builder The {@link SelectBuilder} to be modified. */ private void addColumnsAndJoinsForOneToOneReferences(RelationalPersistentEntity entity, String prefix, @@ -356,8 +363,6 @@ class SqlGenerator { RelationalPersistentEntity entityToDelete = context .getRequiredPersistentEntity(path.getRequiredLeafProperty().getActualType()); - RelationalPersistentProperty property = path.getBaseProperty(); - final String innerMostCondition1 = createInnerMostCondition("%s IS NOT NULL", path); String condition = cascadeConditions(innerMostCondition1, getSubPath(path)); @@ -381,7 +386,8 @@ class SqlGenerator { private String createInnerMostCondition(String template, PersistentPropertyPath path) { PersistentPropertyPath currentPath = path; - while (!currentPath.getParentPath().isEmpty() && !currentPath.getParentPath().getRequiredLeafProperty().isEmbedded()){ + while (!currentPath.getParentPath().isEmpty() + && !currentPath.getParentPath().getRequiredLeafProperty().isEmbedded()) { currentPath = currentPath.getParentPath(); } @@ -408,9 +414,7 @@ class SqlGenerator { ancestor = ancestor.getParentPath(); } - final PersistentPropertyPath extensionForBaseOf = path - .getExtensionForBaseOf(ancestor); - return extensionForBaseOf; + return path.getExtensionForBaseOf(ancestor); } private String cascadeConditions(String innerCondition, PersistentPropertyPath path) { diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/EntityRowMapperUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/EntityRowMapperUnitTests.java index ec9d2426..c836359a 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/EntityRowMapperUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/EntityRowMapperUnitTests.java @@ -149,6 +149,7 @@ public class EntityRowMapperUnitTests { .containsExactly(ID_FOR_ENTITY_NOT_REFERENCING_MAP, "alpha", 24L, "beta"); } + // TODO add additional test for multilevel embeddables @Test // DATAJDBC-111 public void simpleEmbeddedGetsProperlyExtracted() throws SQLException { diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/SqlGeneratorEmbeddedCascadingUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/SqlGeneratorEmbeddedCascadingUnitTests.java deleted file mode 100644 index ac9a628d..00000000 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/SqlGeneratorEmbeddedCascadingUnitTests.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * http://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; - -import static java.util.Collections.*; - -import org.assertj.core.api.SoftAssertions; -import org.junit.Before; -import org.junit.Test; -import org.springframework.data.annotation.Id; -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.RelationalMappingContext; -import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; - -/** - * Unit tests for the {@link SqlGenerator} in a context of the {@link Embedded} annotation. - * - * @author Bastian Wilhelm - */ -public class SqlGeneratorEmbeddedCascadingUnitTests { - - private SqlGenerator sqlGenerator; - - @Before - public void setUp() { - this.sqlGenerator = createSqlGenerator(DummyEntity.class); - } - - SqlGenerator createSqlGenerator(Class type) { - RelationalMappingContext context = new JdbcMappingContext(); - RelationalPersistentEntity persistentEntity = context.getRequiredPersistentEntity(type); - return new SqlGenerator(context, persistentEntity, new SqlGeneratorSource(context)); - } - - @Test // DATAJDBC-111 - public void findOne() { - final String sql = sqlGenerator.getFindOne(); - - SoftAssertions softAssertions = new SoftAssertions(); - softAssertions.assertThat(sql) - .startsWith("SELECT") - .contains("dummy_entity.id1 AS id1") - .contains("dummy_entity.test AS test") - .contains("dummy_entity.attr1 AS attr1") - .contains("dummy_entity.attr2 AS attr2") - .contains("dummy_entity.prefix2_attr1 AS prefix2_attr1") - .contains("dummy_entity.prefix2_attr2 AS prefix2_attr2") - .contains("dummy_entity.prefix_test AS prefix_test") - .contains("dummy_entity.prefix_attr1 AS prefix_attr1") - .contains("dummy_entity.prefix_attr2 AS prefix_attr2") - .contains("dummy_entity.prefix_prefix2_attr1 AS prefix_prefix2_attr1") - .contains("dummy_entity.prefix_prefix2_attr2 AS prefix_prefix2_attr2") - .contains("WHERE dummy_entity.id1 = :id") - .doesNotContain("JOIN").doesNotContain("embeddable"); - softAssertions.assertAll(); - } - - @Test // DATAJDBC-111 - public void findAll() { - final String sql = sqlGenerator.getFindAll(); - - SoftAssertions softAssertions = new SoftAssertions(); - softAssertions.assertThat(sql) - .startsWith("SELECT") - .contains("dummy_entity.id1 AS id1") - .contains("dummy_entity.test AS test") - .contains("dummy_entity.attr1 AS attr1") - .contains("dummy_entity.attr2 AS attr2") - .contains("dummy_entity.prefix2_attr1 AS prefix2_attr1") - .contains("dummy_entity.prefix2_attr2 AS prefix2_attr2") - .contains("dummy_entity.prefix_test AS prefix_test") - .contains("dummy_entity.prefix_attr1 AS prefix_attr1") - .contains("dummy_entity.prefix_attr2 AS prefix_attr2") - .contains("dummy_entity.prefix_prefix2_attr1 AS prefix_prefix2_attr1") - .contains("dummy_entity.prefix_prefix2_attr2 AS prefix_prefix2_attr2") - .doesNotContain("JOIN").doesNotContain("embeddable"); - softAssertions.assertAll(); - } - - @Test // DATAJDBC-111 - public void findAllInList() { - final String sql = sqlGenerator.getFindAllInList(); - - SoftAssertions softAssertions = new SoftAssertions(); - softAssertions.assertThat(sql) - .startsWith("SELECT") - .contains("dummy_entity.id1 AS id1") - .contains("dummy_entity.test AS test") - .contains("dummy_entity.attr1 AS attr1") - .contains("dummy_entity.attr2 AS attr2") - .contains("dummy_entity.prefix2_attr1 AS prefix2_attr1") - .contains("dummy_entity.prefix2_attr2 AS prefix2_attr2") - .contains("dummy_entity.prefix_test AS prefix_test") - .contains("dummy_entity.prefix_attr1 AS prefix_attr1") - .contains("dummy_entity.prefix_attr2 AS prefix_attr2") - .contains("dummy_entity.prefix_prefix2_attr1 AS prefix_prefix2_attr1") - .contains("dummy_entity.prefix_prefix2_attr2 AS prefix_prefix2_attr2") - .contains("WHERE dummy_entity.id1 in(:ids)") - .doesNotContain("JOIN").doesNotContain("embeddable"); - softAssertions.assertAll(); - } - - @Test // DATAJDBC-111 - public void insert() { - final String sql = sqlGenerator.getInsert(emptySet()); - - SoftAssertions softAssertions = new SoftAssertions(); - softAssertions.assertThat(sql) - .startsWith("INSERT INTO") - .contains("dummy_entity") - .contains(":test") - .contains(":attr1") - .contains(":attr2") - .contains(":prefix2_attr1") - .contains(":prefix2_attr2") - .contains(":prefix_test") - .contains(":prefix_attr1") - .contains(":prefix_attr2") - .contains(":prefix_prefix2_attr1") - .contains(":prefix_prefix2_attr2"); - softAssertions.assertAll(); - } - - @Test // DATAJDBC-111 - public void update() { - final String sql = sqlGenerator.getUpdate(); - - SoftAssertions softAssertions = new SoftAssertions(); - softAssertions.assertThat(sql) - .startsWith("UPDATE") - .contains("dummy_entity") - .contains("test = :test") - .contains("attr1 = :attr1") - .contains("attr2 = :attr2") - .contains("prefix2_attr1 = :prefix2_attr1") - .contains("prefix2_attr2 = :prefix2_attr2") - .contains("prefix_test = :prefix_test") - .contains("prefix_attr1 = :prefix_attr1") - .contains("prefix_attr2 = :prefix_attr2") - .contains("prefix_prefix2_attr1 = :prefix_prefix2_attr1") - .contains("prefix_prefix2_attr2 = :prefix_prefix2_attr2"); - softAssertions.assertAll(); - } - - @SuppressWarnings("unused") - static class DummyEntity { - - @Column("id1") - @Id - Long id; - - @Embedded("prefix_") - CascadedEmbedded prefixedEmbeddable; - - @Embedded - CascadedEmbedded embeddable; - } - - @SuppressWarnings("unused") - static class CascadedEmbedded - { - String test; - @Embedded("prefix2_") Embeddable prefixedEmbeddable; - @Embedded Embeddable embeddable; - } - - @SuppressWarnings("unused") - static class Embeddable - { - Long attr1; - String attr2; - } -} diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/SqlGeneratorEmbeddedUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/SqlGeneratorEmbeddedUnitTests.java index b8952470..c0dd0396 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/SqlGeneratorEmbeddedUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/SqlGeneratorEmbeddedUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2019 the original author or authors. + * Copyright 2019 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. @@ -15,22 +15,17 @@ */ package org.springframework.data.jdbc.core; +import static java.util.Collections.*; + import org.assertj.core.api.SoftAssertions; import org.junit.Before; import org.junit.Test; import org.springframework.data.annotation.Id; 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.Column; import org.springframework.data.relational.core.mapping.Embedded; -import org.springframework.data.relational.core.mapping.NamingStrategy; 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 static java.util.Collections.emptySet; -import static org.assertj.core.api.Assertions.assertThat; /** * Unit tests for the {@link SqlGenerator} in a context of the {@link Embedded} annotation. @@ -60,10 +55,16 @@ public class SqlGeneratorEmbeddedUnitTests { softAssertions.assertThat(sql) .startsWith("SELECT") .contains("dummy_entity.id1 AS id1") + .contains("dummy_entity.test AS test") .contains("dummy_entity.attr1 AS attr1") .contains("dummy_entity.attr2 AS attr2") + .contains("dummy_entity.prefix2_attr1 AS prefix2_attr1") + .contains("dummy_entity.prefix2_attr2 AS prefix2_attr2") + .contains("dummy_entity.prefix_test AS prefix_test") .contains("dummy_entity.prefix_attr1 AS prefix_attr1") .contains("dummy_entity.prefix_attr2 AS prefix_attr2") + .contains("dummy_entity.prefix_prefix2_attr1 AS prefix_prefix2_attr1") + .contains("dummy_entity.prefix_prefix2_attr2 AS prefix_prefix2_attr2") .contains("WHERE dummy_entity.id1 = :id") .doesNotContain("JOIN").doesNotContain("embeddable"); softAssertions.assertAll(); @@ -77,10 +78,16 @@ public class SqlGeneratorEmbeddedUnitTests { softAssertions.assertThat(sql) .startsWith("SELECT") .contains("dummy_entity.id1 AS id1") + .contains("dummy_entity.test AS test") .contains("dummy_entity.attr1 AS attr1") .contains("dummy_entity.attr2 AS attr2") + .contains("dummy_entity.prefix2_attr1 AS prefix2_attr1") + .contains("dummy_entity.prefix2_attr2 AS prefix2_attr2") + .contains("dummy_entity.prefix_test AS prefix_test") .contains("dummy_entity.prefix_attr1 AS prefix_attr1") .contains("dummy_entity.prefix_attr2 AS prefix_attr2") + .contains("dummy_entity.prefix_prefix2_attr1 AS prefix_prefix2_attr1") + .contains("dummy_entity.prefix_prefix2_attr2 AS prefix_prefix2_attr2") .doesNotContain("JOIN").doesNotContain("embeddable"); softAssertions.assertAll(); } @@ -93,10 +100,16 @@ public class SqlGeneratorEmbeddedUnitTests { softAssertions.assertThat(sql) .startsWith("SELECT") .contains("dummy_entity.id1 AS id1") + .contains("dummy_entity.test AS test") .contains("dummy_entity.attr1 AS attr1") .contains("dummy_entity.attr2 AS attr2") + .contains("dummy_entity.prefix2_attr1 AS prefix2_attr1") + .contains("dummy_entity.prefix2_attr2 AS prefix2_attr2") + .contains("dummy_entity.prefix_test AS prefix_test") .contains("dummy_entity.prefix_attr1 AS prefix_attr1") .contains("dummy_entity.prefix_attr2 AS prefix_attr2") + .contains("dummy_entity.prefix_prefix2_attr1 AS prefix_prefix2_attr1") + .contains("dummy_entity.prefix_prefix2_attr2 AS prefix_prefix2_attr2") .contains("WHERE dummy_entity.id1 in(:ids)") .doesNotContain("JOIN").doesNotContain("embeddable"); softAssertions.assertAll(); @@ -110,10 +123,16 @@ public class SqlGeneratorEmbeddedUnitTests { softAssertions.assertThat(sql) .startsWith("INSERT INTO") .contains("dummy_entity") + .contains(":test") .contains(":attr1") .contains(":attr2") + .contains(":prefix2_attr1") + .contains(":prefix2_attr2") + .contains(":prefix_test") .contains(":prefix_attr1") - .contains(":prefix_attr2"); + .contains(":prefix_attr2") + .contains(":prefix_prefix2_attr1") + .contains(":prefix_prefix2_attr2"); softAssertions.assertAll(); } @@ -125,10 +144,16 @@ public class SqlGeneratorEmbeddedUnitTests { softAssertions.assertThat(sql) .startsWith("UPDATE") .contains("dummy_entity") + .contains("test = :test") .contains("attr1 = :attr1") .contains("attr2 = :attr2") + .contains("prefix2_attr1 = :prefix2_attr1") + .contains("prefix2_attr2 = :prefix2_attr2") + .contains("prefix_test = :prefix_test") .contains("prefix_attr1 = :prefix_attr1") - .contains("prefix_attr2 = :prefix_attr2"); + .contains("prefix_attr2 = :prefix_attr2") + .contains("prefix_prefix2_attr1 = :prefix_prefix2_attr1") + .contains("prefix_prefix2_attr2 = :prefix_prefix2_attr2"); softAssertions.assertAll(); } @@ -140,10 +165,18 @@ public class SqlGeneratorEmbeddedUnitTests { Long id; @Embedded("prefix_") - Embeddable prefixedEmbeddable; + CascadedEmbedded prefixedEmbeddable; @Embedded - Embeddable embeddable; + CascadedEmbedded embeddable; + } + + @SuppressWarnings("unused") + static class CascadedEmbedded + { + String test; + @Embedded("prefix2_") Embeddable prefixedEmbeddable; + @Embedded Embeddable embeddable; } @SuppressWarnings("unused") diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedCascadingIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedCascadingIntegrationTests.java deleted file mode 100644 index 3929c1fb..00000000 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedCascadingIntegrationTests.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright 2017-2019 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 - * - * http://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.repository; - -import static java.util.Arrays.*; -import static org.assertj.core.api.Assertions.*; - -import lombok.Data; - -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.data.annotation.Id; -import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; -import org.springframework.data.jdbc.testing.TestConfiguration; -import org.springframework.data.relational.core.mapping.Embedded; -import org.springframework.data.repository.CrudRepository; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.rules.SpringClassRule; -import org.springframework.test.context.junit4.rules.SpringMethodRule; -import org.springframework.test.jdbc.JdbcTestUtils; -import org.springframework.transaction.annotation.Transactional; - -/** - * Very simple use cases for creation and usage of JdbcRepositories with test {@link Embedded} annotation in Entities. - * - * @author Bastian Wilhelm - */ -@ContextConfiguration -@Transactional -public class JdbcRepositoryEmbeddedCascadingIntegrationTests { - - @Configuration - @Import(TestConfiguration.class) - static class Config { - - @Autowired JdbcRepositoryFactory factory; - - @Bean - Class testClass() { - return JdbcRepositoryEmbeddedCascadingIntegrationTests.class; - } - - @Bean - DummyEntityRepository dummyEntityRepository() { - return factory.getRepository(DummyEntityRepository.class); - } - - } - - @ClassRule public static final SpringClassRule classRule = new SpringClassRule(); - @Rule public SpringMethodRule methodRule = new SpringMethodRule(); - - @Autowired NamedParameterJdbcTemplate template; - @Autowired DummyEntityRepository repository; - - @Test // DATAJDBC-111 - public void savesAnEntity() { - - DummyEntity entity = repository.save(createDummyEntity()); - - assertThat(JdbcTestUtils.countRowsInTableWhere((JdbcTemplate) template.getJdbcOperations(), "dummy_entity", - "id = " + entity.getId())).isEqualTo(1); - } - - @Test // DATAJDBC-111 - public void saveAndLoadAnEntity() { - - DummyEntity entity = repository.save(createDummyEntity()); - - assertThat(repository.findById(entity.getId())).hasValueSatisfying(it -> { - assertThat(it.getId()).isEqualTo(entity.getId()); - assertThat(it.getPrefixedEmbeddable().getTest()).isEqualTo(entity.getPrefixedEmbeddable().getTest()); - assertThat(it.getPrefixedEmbeddable().getEmbeddable().getAttr()).isEqualTo(entity.getPrefixedEmbeddable().getEmbeddable().getAttr()); - assertThat(it.getEmbeddable().getTest()).isEqualTo(entity.getEmbeddable().getTest()); - assertThat(it.getEmbeddable().getEmbeddable().getAttr()).isEqualTo(entity.getEmbeddable().getEmbeddable().getAttr()); - }); - } - - @Test // DATAJDBC-111 - public void findAllFindsAllEntities() { - - DummyEntity entity = repository.save(createDummyEntity()); - DummyEntity other = repository.save(createDummyEntity()); - - Iterable all = repository.findAll(); - - assertThat(all)// - .extracting(DummyEntity::getId)// - .containsExactlyInAnyOrder(entity.getId(), other.getId()); - } - - @Test // DATAJDBC-111 - public void findByIdReturnsEmptyWhenNoneFound() { - - // NOT saving anything, so DB is empty - assertThat(repository.findById(-1L)).isEmpty(); - } - - @Test // DATAJDBC-111 - public void update() { - - DummyEntity entity = repository.save(createDummyEntity()); - - entity.getPrefixedEmbeddable().setTest("something else"); - entity.getPrefixedEmbeddable().getEmbeddable().setAttr(3L); - DummyEntity saved = repository.save(entity); - - assertThat(repository.findById(entity.getId())).hasValueSatisfying(it -> { - assertThat(it.getPrefixedEmbeddable().getTest()).isEqualTo(saved.getPrefixedEmbeddable().getTest()); - assertThat(it.getPrefixedEmbeddable().getEmbeddable().getAttr()).isEqualTo(saved.getPrefixedEmbeddable().getEmbeddable().getAttr()); - }); - } - - @Test // DATAJDBC-111 - public void updateMany() { - - DummyEntity entity = repository.save(createDummyEntity()); - DummyEntity other = repository.save(createDummyEntity()); - - entity.getEmbeddable().setTest("something else"); - other.getEmbeddable().setTest("others Name"); - - entity.getPrefixedEmbeddable().getEmbeddable().setAttr(3L); - other.getPrefixedEmbeddable().getEmbeddable().setAttr(5L); - - repository.saveAll(asList(entity, other)); - - assertThat(repository.findAll()) // - .extracting(d -> d.getEmbeddable().getTest()) // - .containsExactlyInAnyOrder(entity.getEmbeddable().getTest(), other.getEmbeddable().getTest()); - - assertThat(repository.findAll()) // - .extracting(d -> d.getPrefixedEmbeddable().getEmbeddable().getAttr()) // - .containsExactlyInAnyOrder(entity.getPrefixedEmbeddable().getEmbeddable().getAttr(), other.getPrefixedEmbeddable().getEmbeddable().getAttr()); - } - - @Test // DATAJDBC-111 - public void deleteById() { - - DummyEntity one = repository.save(createDummyEntity()); - DummyEntity two = repository.save(createDummyEntity()); - DummyEntity three = repository.save(createDummyEntity()); - - repository.deleteById(two.getId()); - - assertThat(repository.findAll()) // - .extracting(DummyEntity::getId) // - .containsExactlyInAnyOrder(one.getId(), three.getId()); - } - - @Test // DATAJDBC-111 - public void deleteByEntity() { - DummyEntity one = repository.save(createDummyEntity()); - DummyEntity two = repository.save(createDummyEntity()); - DummyEntity three = repository.save(createDummyEntity()); - - repository.delete(one); - - assertThat(repository.findAll()) // - .extracting(DummyEntity::getId) // - .containsExactlyInAnyOrder(two.getId(), three.getId()); - } - - @Test // DATAJDBC-111 - public void deleteByList() { - - DummyEntity one = repository.save(createDummyEntity()); - DummyEntity two = repository.save(createDummyEntity()); - DummyEntity three = repository.save(createDummyEntity()); - - repository.deleteAll(asList(one, three)); - - assertThat(repository.findAll()) // - .extracting(DummyEntity::getId) // - .containsExactlyInAnyOrder(two.getId()); - } - - @Test // DATAJDBC-111 - public void deleteAll() { - - repository.save(createDummyEntity()); - repository.save(createDummyEntity()); - repository.save(createDummyEntity()); - - assertThat(repository.findAll()).isNotEmpty(); - - repository.deleteAll(); - - assertThat(repository.findAll()).isEmpty(); - } - - - private static DummyEntity createDummyEntity() { - DummyEntity entity = new DummyEntity(); - - final CascadedEmbeddable prefixedCascadedEmbeddable = new CascadedEmbeddable(); - prefixedCascadedEmbeddable.setTest("c1"); - - final Embeddable embeddable1 = new Embeddable(); - embeddable1.setAttr(1L); - prefixedCascadedEmbeddable.setEmbeddable(embeddable1); - - entity.setPrefixedEmbeddable(prefixedCascadedEmbeddable); - - - final CascadedEmbeddable cascadedEmbeddable = new CascadedEmbeddable(); - cascadedEmbeddable.setTest("c2"); - - final Embeddable embeddable2 = new Embeddable(); - embeddable2.setAttr(2L); - cascadedEmbeddable.setEmbeddable(embeddable2); - - entity.setEmbeddable(cascadedEmbeddable); - - return entity; - } - - interface DummyEntityRepository extends CrudRepository {} - - @Data - static class DummyEntity { - - @Id Long id; - - @Embedded("prefix_") CascadedEmbeddable prefixedEmbeddable; - - @Embedded CascadedEmbeddable embeddable; - } - - @Data - static class CascadedEmbeddable { - String test; - - @Embedded("prefix2_") - Embeddable embeddable; - } - - @Data - static class Embeddable { - Long attr; - } -} diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedImmutableIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedImmutableIntegrationTests.java index cc9972fd..92352c58 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedImmutableIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedImmutableIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2019 the original author or authors. + * Copyright 2019 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. @@ -75,15 +75,6 @@ public class JdbcRepositoryEmbeddedImmutableIntegrationTests { @Autowired NamedParameterJdbcTemplate template; @Autowired DummyEntityRepository repository; - @Test // DATAJDBC-111 - public void savesAnEntity() { - - DummyEntity entity = repository.save(createDummyEntity()); - - assertThat(JdbcTestUtils.countRowsInTableWhere((JdbcTemplate) template.getJdbcOperations(), "dummy_entity", - "id = " + entity.getId())).isEqualTo(1); - } - @Test // DATAJDBC-111 public void saveAndLoadAnEntity() { @@ -96,121 +87,14 @@ public class JdbcRepositoryEmbeddedImmutableIntegrationTests { }); } - @Test // DATAJDBC-111 - public void findAllFindsAllEntities() { - - DummyEntity entity = repository.save(createDummyEntity()); - DummyEntity other = repository.save(createDummyEntity()); - - Iterable all = repository.findAll(); - - assertThat(all)// - .extracting(DummyEntity::getId)// - .containsExactlyInAnyOrder(entity.getId(), other.getId()); - } - - @Test // DATAJDBC-111 - public void findByIdReturnsEmptyWhenNoneFound() { - - // NOT saving anything, so DB is empty - assertThat(repository.findById(-1L)).isEmpty(); - } - - @Test // DATAJDBC-111 - public void update() { - - DummyEntity entity = repository.save(createDummyEntity()); - - entity.setPrefixedEmbeddable(entity.getPrefixedEmbeddable().withAttr2("something else")); - DummyEntity saved = repository.save(entity); - - assertThat(repository.findById(entity.getId())).hasValueSatisfying(it -> { - assertThat(it.getPrefixedEmbeddable().getAttr2()).isEqualTo(saved.getPrefixedEmbeddable().getAttr2()); - }); - } - - @Test // DATAJDBC-111 - public void updateMany() { - - DummyEntity entity = repository.save(createDummyEntity()); - DummyEntity other = repository.save(createDummyEntity()); - - entity.setPrefixedEmbeddable(entity.getPrefixedEmbeddable().withAttr2("something else")); - other.setPrefixedEmbeddable(entity.getPrefixedEmbeddable().withAttr2("others Name")); - - repository.saveAll(asList(entity, other)); - - assertThat(repository.findAll()) // - .extracting(d -> d.getPrefixedEmbeddable().getAttr2()) // - .containsExactlyInAnyOrder(entity.getPrefixedEmbeddable().getAttr2(), other.getPrefixedEmbeddable().getAttr2()); - } - - @Test // DATAJDBC-111 - public void deleteById() { - - DummyEntity one = repository.save(createDummyEntity()); - DummyEntity two = repository.save(createDummyEntity()); - DummyEntity three = repository.save(createDummyEntity()); - - repository.deleteById(two.getId()); - - assertThat(repository.findAll()) // - .extracting(DummyEntity::getId) // - .containsExactlyInAnyOrder(one.getId(), three.getId()); - } - - @Test // DATAJDBC-111 - public void deleteByEntity() { - DummyEntity one = repository.save(createDummyEntity()); - DummyEntity two = repository.save(createDummyEntity()); - DummyEntity three = repository.save(createDummyEntity()); - - repository.delete(one); - - assertThat(repository.findAll()) // - .extracting(DummyEntity::getId) // - .containsExactlyInAnyOrder(two.getId(), three.getId()); - } - - @Test // DATAJDBC-111 - public void deleteByList() { - - DummyEntity one = repository.save(createDummyEntity()); - DummyEntity two = repository.save(createDummyEntity()); - DummyEntity three = repository.save(createDummyEntity()); - - repository.deleteAll(asList(one, three)); - - assertThat(repository.findAll()) // - .extracting(DummyEntity::getId) // - .containsExactlyInAnyOrder(two.getId()); - } - - @Test // DATAJDBC-111 - public void deleteAll() { - - repository.save(createDummyEntity()); - repository.save(createDummyEntity()); - repository.save(createDummyEntity()); - - assertThat(repository.findAll()).isNotEmpty(); - - repository.deleteAll(); - - assertThat(repository.findAll()).isEmpty(); - } - private static DummyEntity createDummyEntity() { - DummyEntity entity = new DummyEntity(); - - entity.setPrefixedEmbeddable(new Embeddable(1L, "test1")); - - return entity; + return new DummyEntity(null, new Embeddable(1L, "test1")); } interface DummyEntityRepository extends CrudRepository {} - @Data + @Value + @Wither static class DummyEntity { @Id Long id; @@ -221,6 +105,7 @@ public class JdbcRepositoryEmbeddedImmutableIntegrationTests { @Value @Wither private static class Embeddable { + Long attr1; String attr2; } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedIntegrationTests.java index 28a7cf83..391607d4 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2019 the original author or authors. + * Copyright 2019 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. @@ -41,7 +41,7 @@ import org.springframework.test.jdbc.JdbcTestUtils; import org.springframework.transaction.annotation.Transactional; /** - * Very simple use cases for creation and usage of JdbcRepositories with {@link Embedded} annotation in Entities. + * Very simple use cases for creation and usage of JdbcRepositories with test {@link Embedded} annotation in Entities. * * @author Bastian Wilhelm */ @@ -89,10 +89,10 @@ public class JdbcRepositoryEmbeddedIntegrationTests { assertThat(repository.findById(entity.getId())).hasValueSatisfying(it -> { assertThat(it.getId()).isEqualTo(entity.getId()); - assertThat(it.getPrefixedEmbeddable().getAttr1()).isEqualTo(entity.getPrefixedEmbeddable().getAttr1()); - assertThat(it.getPrefixedEmbeddable().getAttr2()).isEqualTo(entity.getPrefixedEmbeddable().getAttr2()); - assertThat(it.getEmbeddable().getAttr1()).isEqualTo(entity.getEmbeddable().getAttr1()); - assertThat(it.getEmbeddable().getAttr2()).isEqualTo(entity.getEmbeddable().getAttr2()); + assertThat(it.getPrefixedEmbeddable().getTest()).isEqualTo(entity.getPrefixedEmbeddable().getTest()); + assertThat(it.getPrefixedEmbeddable().getEmbeddable().getAttr()).isEqualTo(entity.getPrefixedEmbeddable().getEmbeddable().getAttr()); + assertThat(it.getEmbeddable().getTest()).isEqualTo(entity.getEmbeddable().getTest()); + assertThat(it.getEmbeddable().getEmbeddable().getAttr()).isEqualTo(entity.getEmbeddable().getEmbeddable().getAttr()); }); } @@ -121,11 +121,13 @@ public class JdbcRepositoryEmbeddedIntegrationTests { DummyEntity entity = repository.save(createDummyEntity()); - entity.getPrefixedEmbeddable().setAttr2("something else"); + entity.getPrefixedEmbeddable().setTest("something else"); + entity.getPrefixedEmbeddable().getEmbeddable().setAttr(3L); DummyEntity saved = repository.save(entity); assertThat(repository.findById(entity.getId())).hasValueSatisfying(it -> { - assertThat(it.getPrefixedEmbeddable().getAttr2()).isEqualTo(saved.getPrefixedEmbeddable().getAttr2()); + assertThat(it.getPrefixedEmbeddable().getTest()).isEqualTo(saved.getPrefixedEmbeddable().getTest()); + assertThat(it.getPrefixedEmbeddable().getEmbeddable().getAttr()).isEqualTo(saved.getPrefixedEmbeddable().getEmbeddable().getAttr()); }); } @@ -135,14 +137,21 @@ public class JdbcRepositoryEmbeddedIntegrationTests { DummyEntity entity = repository.save(createDummyEntity()); DummyEntity other = repository.save(createDummyEntity()); - entity.getEmbeddable().setAttr2("something else"); - other.getEmbeddable().setAttr2("others Name"); + entity.getEmbeddable().setTest("something else"); + other.getEmbeddable().setTest("others Name"); + + entity.getPrefixedEmbeddable().getEmbeddable().setAttr(3L); + other.getPrefixedEmbeddable().getEmbeddable().setAttr(5L); repository.saveAll(asList(entity, other)); assertThat(repository.findAll()) // - .extracting(d -> d.getEmbeddable().getAttr2()) // - .containsExactlyInAnyOrder(entity.getEmbeddable().getAttr2(), other.getEmbeddable().getAttr2()); + .extracting(d -> d.getEmbeddable().getTest()) // + .containsExactlyInAnyOrder(entity.getEmbeddable().getTest(), other.getEmbeddable().getTest()); + + assertThat(repository.findAll()) // + .extracting(d -> d.getPrefixedEmbeddable().getEmbeddable().getAttr()) // + .containsExactlyInAnyOrder(entity.getPrefixedEmbeddable().getEmbeddable().getAttr(), other.getPrefixedEmbeddable().getEmbeddable().getAttr()); } @Test // DATAJDBC-111 @@ -200,18 +209,28 @@ public class JdbcRepositoryEmbeddedIntegrationTests { assertThat(repository.findAll()).isEmpty(); } + private static DummyEntity createDummyEntity() { DummyEntity entity = new DummyEntity(); - final Embeddable prefixedEmbeddable = new Embeddable(); - prefixedEmbeddable.setAttr1(1L); - prefixedEmbeddable.setAttr2("test1"); - entity.setPrefixedEmbeddable(prefixedEmbeddable); + final CascadedEmbeddable prefixedCascadedEmbeddable = new CascadedEmbeddable(); + prefixedCascadedEmbeddable.setTest("c1"); - final Embeddable embeddable = new Embeddable(); - embeddable.setAttr1(2L); - embeddable.setAttr2("test2"); - entity.setEmbeddable(embeddable); + final Embeddable embeddable1 = new Embeddable(); + embeddable1.setAttr(1L); + prefixedCascadedEmbeddable.setEmbeddable(embeddable1); + + entity.setPrefixedEmbeddable(prefixedCascadedEmbeddable); + + + final CascadedEmbeddable cascadedEmbeddable = new CascadedEmbeddable(); + cascadedEmbeddable.setTest("c2"); + + final Embeddable embeddable2 = new Embeddable(); + embeddable2.setAttr(2L); + cascadedEmbeddable.setEmbeddable(embeddable2); + + entity.setEmbeddable(cascadedEmbeddable); return entity; } @@ -223,14 +242,21 @@ public class JdbcRepositoryEmbeddedIntegrationTests { @Id Long id; - @Embedded("prefix_") Embeddable prefixedEmbeddable; + @Embedded("prefix_") CascadedEmbeddable prefixedEmbeddable; - @Embedded Embeddable embeddable; + @Embedded CascadedEmbeddable embeddable; + } + + @Data + static class CascadedEmbeddable { + String test; + + @Embedded("prefix2_") + Embeddable embeddable; } @Data static class Embeddable { - Long attr1; - String attr2; + Long attr; } } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedNotInAggregateRootIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedNotInAggregateRootIntegrationTests.java index 74c3100e..3354e1ab 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedNotInAggregateRootIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedNotInAggregateRootIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2019 the original author or authors. + * Copyright 2019 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. diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests.java index 3556c70f..e965e376 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2019 the original author or authors. + * Copyright 2019 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. diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedWithReferenceIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedWithReferenceIntegrationTests.java index a2ca6275..737a5565 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedWithReferenceIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedWithReferenceIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2019 the original author or authors. + * Copyright 2019 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. diff --git a/spring-data-jdbc/src/test/resources/container-license-acceptance.txt b/spring-data-jdbc/src/test/resources/container-license-acceptance.txt new file mode 100644 index 00000000..b546fb08 --- /dev/null +++ b/spring-data-jdbc/src/test/resources/container-license-acceptance.txt @@ -0,0 +1 @@ +microsoft/mssql-server-linux:2017-CU6 \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-hsql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-hsql.sql deleted file mode 100644 index b6619706..00000000 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-hsql.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE TABLE dummy_entity ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, TEST VARCHAR(100), PREFIX2_ATTR BIGINT, PREFIX_TEST VARCHAR(100), PREFIX_PREFIX2_ATTR BIGINT) diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-mariadb.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-mariadb.sql deleted file mode 100644 index 2faa643a..00000000 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-mariadb.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE TABLE dummy_entity (id BIGINT AUTO_INCREMENT PRIMARY KEY, TEST VARCHAR(100), PREFIX2_ATTR BIGINT, PREFIX_TEST VARCHAR(100), PREFIX_PREFIX2_ATTR BIGINT); diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-mssql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-mssql.sql deleted file mode 100644 index 2832a7ac..00000000 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-mssql.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP TABLE IF EXISTS dummy_entity; -CREATE TABLE dummy_entity (id BIGINT IDENTITY PRIMARY KEY, TEST VARCHAR(100), PREFIX2_ATTR BIGINT, PREFIX_TEST VARCHAR(100), PREFIX_PREFIX2_ATTR BIGINT); diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-mysql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-mysql.sql deleted file mode 100644 index 2faa643a..00000000 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-mysql.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE TABLE dummy_entity (id BIGINT AUTO_INCREMENT PRIMARY KEY, TEST VARCHAR(100), PREFIX2_ATTR BIGINT, PREFIX_TEST VARCHAR(100), PREFIX_PREFIX2_ATTR BIGINT); diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-postgres.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-postgres.sql deleted file mode 100644 index a5d589d4..00000000 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedCascadingIntegrationTests-postgres.sql +++ /dev/null @@ -1,2 +0,0 @@ -DROP TABLE dummy_entity; -CREATE TABLE dummy_entity (id SERIAL PRIMARY KEY, TEST VARCHAR(100), PREFIX2_ATTR BIGINT, PREFIX_TEST VARCHAR(100), PREFIX_PREFIX2_ATTR BIGINT); diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-hsql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-hsql.sql index 35cb6a1f..b6619706 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-hsql.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-hsql.sql @@ -1 +1 @@ -CREATE TABLE dummy_entity ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, ATTR1 BIGINT, ATTR2 VARCHAR(100), PREFIX_ATTR1 BIGINT, PREFIX_ATTR2 VARCHAR(100)) +CREATE TABLE dummy_entity ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, TEST VARCHAR(100), PREFIX2_ATTR BIGINT, PREFIX_TEST VARCHAR(100), PREFIX_PREFIX2_ATTR BIGINT) diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-mariadb.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-mariadb.sql index 925f601b..2faa643a 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-mariadb.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-mariadb.sql @@ -1 +1 @@ -CREATE TABLE dummy_entity (id BIGINT AUTO_INCREMENT PRIMARY KEY, ATTR1 BIGINT, ATTR2 VARCHAR(100), PREFIX_ATTR1 BIGINT, PREFIX_ATTR2 VARCHAR(100)); +CREATE TABLE dummy_entity (id BIGINT AUTO_INCREMENT PRIMARY KEY, TEST VARCHAR(100), PREFIX2_ATTR BIGINT, PREFIX_TEST VARCHAR(100), PREFIX_PREFIX2_ATTR BIGINT); diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-mssql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-mssql.sql index 2eb4f770..2832a7ac 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-mssql.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-mssql.sql @@ -1,2 +1,2 @@ DROP TABLE IF EXISTS dummy_entity; -CREATE TABLE dummy_entity (id BIGINT IDENTITY PRIMARY KEY, ATTR1 BIGINT, ATTR2 VARCHAR(100), PREFIX_ATTR1 BIGINT, PREFIX_ATTR2 VARCHAR(100)); +CREATE TABLE dummy_entity (id BIGINT IDENTITY PRIMARY KEY, TEST VARCHAR(100), PREFIX2_ATTR BIGINT, PREFIX_TEST VARCHAR(100), PREFIX_PREFIX2_ATTR BIGINT); diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-mysql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-mysql.sql index 925f601b..2faa643a 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-mysql.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-mysql.sql @@ -1 +1 @@ -CREATE TABLE dummy_entity (id BIGINT AUTO_INCREMENT PRIMARY KEY, ATTR1 BIGINT, ATTR2 VARCHAR(100), PREFIX_ATTR1 BIGINT, PREFIX_ATTR2 VARCHAR(100)); +CREATE TABLE dummy_entity (id BIGINT AUTO_INCREMENT PRIMARY KEY, TEST VARCHAR(100), PREFIX2_ATTR BIGINT, PREFIX_TEST VARCHAR(100), PREFIX_PREFIX2_ATTR BIGINT); diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-postgres.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-postgres.sql index 3b298205..a5d589d4 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-postgres.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedIntegrationTests-postgres.sql @@ -1,2 +1,2 @@ DROP TABLE dummy_entity; -CREATE TABLE dummy_entity (id SERIAL PRIMARY KEY, ATTR1 BIGINT, ATTR2 VARCHAR(100), PREFIX_ATTR1 BIGINT, PREFIX_ATTR2 VARCHAR(100)); +CREATE TABLE dummy_entity (id SERIAL PRIMARY KEY, TEST VARCHAR(100), PREFIX2_ATTR BIGINT, PREFIX_TEST VARCHAR(100), PREFIX_PREFIX2_ATTR BIGINT); diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/WritingContext.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/WritingContext.java index f33f0da5..10b28740 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/WritingContext.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/WritingContext.java @@ -15,6 +15,13 @@ */ package org.springframework.data.relational.core.conversion; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.mapping.PersistentPropertyPaths; import org.springframework.data.relational.core.mapping.RelationalMappingContext; @@ -23,14 +30,6 @@ import org.springframework.data.util.Pair; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Stack; - /** * Holds context information for the current save operation. * @@ -121,18 +120,20 @@ class WritingContext { List> actions = new ArrayList<>(); from(path).forEach(node -> { - DbAction.Insert insert; - if (node.getPath().getRequiredLeafProperty().isQualified()) { - Pair value = (Pair) node.getValue(); - insert = new DbAction.Insert<>(value.getSecond(), path, getAction(node.getParent())); - insert.getAdditionalValues().put(node.getPath().getRequiredLeafProperty().getKeyColumn(), value.getFirst()); + DbAction.Insert insert; + if (node.getPath().getRequiredLeafProperty().isQualified()) { - } else { - insert = new DbAction.Insert<>(node.getValue(), path, getAction(node.getParent())); - } - previousActions.put(node, insert); - actions.add(insert); + @SuppressWarnings("unchecked") + Pair value = (Pair) node.getValue(); + insert = new DbAction.Insert<>(value.getSecond(), path, getAction(node.getParent())); + insert.getAdditionalValues().put(node.getPath().getRequiredLeafProperty().getKeyColumn(), value.getFirst()); + + } else { + insert = new DbAction.Insert<>(node.getValue(), path, getAction(node.getParent())); + } + previousActions.put(node, insert); + actions.add(insert); }); return actions; @@ -186,12 +187,11 @@ class WritingContext { // return context.getRequiredPersistentEntity(o.getClass()).isNew(o); // } - private List from( - PersistentPropertyPath path) { + private List from(PersistentPropertyPath path) { List nodes = new ArrayList<>(); - if (dependsOnRootIgnoringEmbeddables(path)) { + if (isDirectlyReferencedByRootIgnoringEmbeddables(path)) { Object value = getFromRootValue(path); nodes.addAll(createNodes(path, null, value)); @@ -213,11 +213,14 @@ class WritingContext { return nodes; } - private boolean dependsOnRootIgnoringEmbeddables(PersistentPropertyPath path){ + private boolean isDirectlyReferencedByRootIgnoringEmbeddables( + PersistentPropertyPath path) { + PersistentPropertyPath currentPath = path.getParentPath(); - while (!currentPath.isEmpty()){ - if(!currentPath.getRequiredLeafProperty().isEmbedded()){ + while (!currentPath.isEmpty()) { + + if (!currentPath.getRequiredLeafProperty().isEmbedded()) { return false; } currentPath = currentPath.getParentPath(); @@ -227,32 +230,11 @@ class WritingContext { } @Nullable - private Object getFromRootValue(PersistentPropertyPath path){ - final Stack> stack = new Stack<>(); - PersistentPropertyPath currentPath = path; - - while (!currentPath.isEmpty()){ - stack.push(currentPath); - currentPath = currentPath.getParentPath(); - } - - - Object value = entity; - while (!stack.empty() && value != null){ - currentPath = stack.pop(); - final RelationalPersistentProperty property = currentPath.getRequiredLeafProperty(); - - value = context // - .getRequiredPersistentEntity(property.getOwner().getType()) // - .getPropertyAccessor(value) // - .getProperty(property); - } - - return value; + private Object getFromRootValue(PersistentPropertyPath path) { + return path.getBaseProperty().getOwner().getPropertyAccessor(entity).getProperty(path); } - private List createNodes( - PersistentPropertyPath path, + private List createNodes(PersistentPropertyPath path, @Nullable PathNode parentNode, @Nullable Object value) { if (value == null) { @@ -260,13 +242,12 @@ class WritingContext { } List nodes = new ArrayList<>(); - if(path.getRequiredLeafProperty().isEmbedded()){ + if (path.getRequiredLeafProperty().isEmbedded()) { nodes.add(new PathNode(path, parentNode, value)); } else if (path.getRequiredLeafProperty().isQualified()) { if (path.getRequiredLeafProperty().isMap()) { - ((Map) value) - .forEach((k, v) -> nodes.add(new PathNode(path, parentNode, Pair.of(k, v)))); + ((Map) value).forEach((k, v) -> nodes.add(new PathNode(path, parentNode, Pair.of(k, v)))); } else { List listValue = (List) value; 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 5f34cdfd..cd16d16c 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 @@ -77,16 +77,11 @@ public class BasicRelationalPersistentProperty extends AnnotationBasedPersistent this.context = context; - this.isEmbedded = Lazy.of(() -> Optional.ofNullable( - findAnnotation(Embedded.class)) - .isPresent() - ); + this.isEmbedded = Lazy.of(() -> Optional.ofNullable(findAnnotation(Embedded.class)).isPresent()); - this.embeddedPrefix = Lazy.of(() -> Optional.ofNullable( - findAnnotation(Embedded.class)) - .map(Embedded::value) - .orElse("") - ); + this.embeddedPrefix = Lazy.of(() -> Optional.ofNullable(findAnnotation(Embedded.class)) // + .map(Embedded::value) // + .orElse("")); this.columnName = Lazy.of(() -> Optional.ofNullable( // findAnnotation(Column.class)) // @@ -187,16 +182,12 @@ public class BasicRelationalPersistentProperty extends AnnotationBasedPersistent return isEmbedded.get(); } - @Override - public String getEmbeddedPrefix() { - if(isEmbedded()){ - return embeddedPrefix.get(); - } else { - return null; - } - } + @Override + public String getEmbeddedPrefix() { + return isEmbedded() ? embeddedPrefix.get() : null; + } - private boolean isListLike() { + private boolean isListLike() { return isCollectionLike() && !Set.class.isAssignableFrom(this.getType()); } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/Embedded.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/Embedded.java index 5b169a20..7e9b6ec5 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/Embedded.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/Embedded.java @@ -1,3 +1,18 @@ +/* + * Copyright 2019 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 + * + * http://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.relational.core.mapping; import java.lang.annotation.Documented; diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentProperty.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentProperty.java index d624f843..1040eed8 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentProperty.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalPersistentProperty.java @@ -73,11 +73,15 @@ public interface RelationalPersistentProperty extends PersistentProperty requiredPersistentEntity = context.getRequiredPersistentEntity(DummyEntity.class); + final RelationalPersistentEntity requiredPersistentEntity = context + .getRequiredPersistentEntity(DummyEntity.class); - assertThat(requiredPersistentEntity.getRequiredPersistentProperty("someList").isEmbedded()).isFalse(); - assertThat(requiredPersistentEntity.getRequiredPersistentProperty("someList").getEmbeddedPrefix()).isNull(); + SoftAssertions softly = new SoftAssertions(); - assertThat(requiredPersistentEntity.getRequiredPersistentProperty("id").isEmbedded()).isFalse(); - assertThat(requiredPersistentEntity.getRequiredPersistentProperty("id").getEmbeddedPrefix()).isNull(); + BiConsumer checkEmbedded = (name, prefix) -> { - assertThat(requiredPersistentEntity.getRequiredPersistentProperty("embeddableEntity").isEmbedded()).isTrue(); - assertThat(requiredPersistentEntity.getRequiredPersistentProperty("embeddableEntity").getEmbeddedPrefix()).isEmpty(); + RelationalPersistentProperty property = requiredPersistentEntity.getRequiredPersistentProperty(name); - assertThat(requiredPersistentEntity.getRequiredPersistentProperty("prefixedEmbeddableEntity").isEmbedded()).isTrue(); - assertThat(requiredPersistentEntity.getRequiredPersistentProperty("prefixedEmbeddableEntity").getEmbeddedPrefix()).isEqualTo("prefix"); + softly.assertThat(property.isEmbedded()) // + .describedAs(name + " is embedded") // + .isEqualTo(prefix != null); + + softly.assertThat(property.getEmbeddedPrefix()) // + .describedAs(name + " prefix") // + .isEqualTo(prefix); + }; + + checkEmbedded.accept("someList", null); + checkEmbedded.accept("id", null); + checkEmbedded.accept("embeddableEntity", ""); + checkEmbedded.accept("prefixedEmbeddableEntity", "prefix"); + + softly.assertAll(); } - - private void checkTargetType(SoftAssertions softly, RelationalPersistentEntity persistentEntity, String propertyName, Class expected) { @@ -150,7 +160,6 @@ public class BasicRelationalPersistentPropertyUnitTests { // DATAJDBC-111 private @Embedded("prefix") EmbeddableEntity prefixedEmbeddableEntity; - @Column("dummy_last_updated_at") public LocalDateTime getLocalDateTime() { return localDateTime; @@ -172,7 +181,7 @@ public class BasicRelationalPersistentPropertyUnitTests { // DATAJDBC-111 @Data - private static class EmbeddableEntity{ + private static class EmbeddableEntity { private final String embeddedTest; } } diff --git a/src/main/asciidoc/jdbc.adoc b/src/main/asciidoc/jdbc.adoc index c4ed7bff..880356c6 100644 --- a/src/main/asciidoc/jdbc.adoc +++ b/src/main/asciidoc/jdbc.adoc @@ -124,7 +124,8 @@ The properties of the following types are currently supported: It is optional for one-to-one relationship entities to have an `id` attribute. The table of the referenced entity is expected to have an additional column named the same as the table of the referencing entity. You can change this name by implementing `NamingStrategy.getReverseColumnName(RelationalPersistentProperty property)`. -Embedded entities do not have an `id`. +Embedded entities do not need an `id`. +If one is present it gets ignored. * `Set` is considered a one-to-many relationship. The table of the referenced entity is expected to have an additional column named the same as the table of the referencing entity. @@ -273,7 +274,7 @@ public class MySubEntity { ==== [[jdbc.entity-persistence.embedded-entities]] -=== `Embedded entities` +=== Embedded entities Embedded entities are used to have value objects in your java data model, even if there is only one table in your database. In the following example you see, that `MyEntity` is mapped with the `@Embedded` annotation. @@ -299,7 +300,6 @@ public class EmbeddedEntity { If you need a value object multiple times in an entity, this can be achieved with the optional `value` element of the `@Embedded` annotation. This element represents a prefix and is prepend for each column name in the embedded object. - [[jdbc.entity-persistence.state-detection-strategies]] === Entity State Detection Strategies