From 1703c8011f29e19d1494722f7cd3d2da5baa4cb7 Mon Sep 17 00:00:00 2001 From: Myat Min Date: Sun, 26 Jul 2020 21:51:41 +0800 Subject: [PATCH 1/3] DATAJDBC-584 - Allow sort by entity child field --- .../data/jdbc/core/convert/SqlGenerator.java | 5 +++-- .../data/jdbc/core/convert/SqlGeneratorUnitTests.java | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java index f04177b500..9e86c1d8bc 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java @@ -712,8 +712,9 @@ private List extractOrderByFields(Sort sort) { private OrderByField orderToOrderByField(Sort.Order order) { - SqlIdentifier columnName = this.entity.getRequiredPersistentProperty(order.getProperty()).getColumnName(); - Column column = Column.create(columnName, this.getTable()); + PersistentPropertyPath path = mappingContext.getPersistentPropertyPath(order.getProperty(), this.entity.getType()); + PersistentPropertyPathExtension extPath = new PersistentPropertyPathExtension(mappingContext, path); + Column column = this.getColumn(extPath); return OrderByField.from(column, order.getDirection()); } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java index ec1c8c1e77..e161447986 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlGeneratorUnitTests.java @@ -220,11 +220,11 @@ public void findAllSortedBySingleField() { "ORDER BY x_name ASC"); } - @Test // DATAJDBC-101 + @Test // DATAJDBC-101, DATAJDBC-584 public void findAllSortedByMultipleFields() { String sql = sqlGenerator.getFindAll( - Sort.by(new Sort.Order(Sort.Direction.DESC, "name"), new Sort.Order(Sort.Direction.ASC, "other"))); + Sort.by(new Sort.Order(Sort.Direction.DESC, "name"), new Sort.Order(Sort.Direction.ASC, "ref.content"), new Sort.Order(Sort.Direction.DESC, "ref.further.something"))); assertThat(sql).contains("SELECT", // "dummy_entity.id1 AS id1", // @@ -238,7 +238,8 @@ public void findAllSortedByMultipleFields() { "LEFT OUTER JOIN referenced_entity ref ON ref.dummy_entity = dummy_entity.id1", // "LEFT OUTER JOIN second_level_referenced_entity ref_further ON ref_further.referenced_entity = ref.x_l1id", // "ORDER BY x_name DESC", // - "x_other ASC"); + "ref_x_content ASC", // + "ref_further_x_something DESC" ); } @Test // DATAJDBC-101 From f408369d800b975d999ee04f9a5f505740457e8e Mon Sep 17 00:00:00 2001 From: Myat Min Date: Fri, 31 Jul 2020 02:39:20 +0800 Subject: [PATCH 2/3] DATAJDBC-587 Convert identity value object to SQL type with custom converter in FindAllByPath --- .../convert/DefaultDataAccessStrategy.java | 4 +- .../DefaultDataAccessStrategyUnitTests.java | 113 ++++++++++++++---- 2 files changed, 94 insertions(+), 23 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java index 8b1e729f75..913c391966 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java @@ -367,7 +367,9 @@ private SqlParameterSource createParameterSource(Identifier identifier, Identifi SqlIdentifierParameterSource parameterSource = new SqlIdentifierParameterSource(identifierProcessing); - identifier.toMap().forEach(parameterSource::addValue); + identifier.toMap() + .forEach((sqlIdentifier, value) -> addConvertedPropertyValue(parameterSource, + sqlIdentifier, value, value.getClass())); return parameterSource; } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java index 42cdf12822..6ae82bbfb9 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java @@ -1,17 +1,15 @@ /* * Copyright 2017-2020 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 + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 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.convert; @@ -24,8 +22,10 @@ import lombok.Data; import lombok.RequiredArgsConstructor; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import lombok.Value; import org.junit.Before; @@ -37,11 +37,14 @@ import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.WritingConverter; import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; +import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.relational.core.dialect.Dialect; import org.springframework.data.relational.core.dialect.HsqlDbDialect; import org.springframework.data.relational.core.mapping.RelationalMappingContext; +import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; import org.springframework.data.relational.core.sql.SqlIdentifier; import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.support.KeyHolder; @@ -63,7 +66,8 @@ public class DefaultDataAccessStrategyUnitTests { RelationalMappingContext context = new JdbcMappingContext(); HashMap additionalParameters = new HashMap<>(); - ArgumentCaptor paramSourceCaptor = ArgumentCaptor.forClass(SqlParameterSource.class); + ArgumentCaptor paramSourceCaptor = + ArgumentCaptor.forClass(SqlParameterSource.class); JdbcConverter converter; DefaultDataAccessStrategy accessStrategy; @@ -90,7 +94,8 @@ public void additionalParameterForIdDoesNotLeadToDuplicateParameters() { additionalParameters.put(SqlIdentifier.quoted("ID"), ID_FROM_ADDITIONAL_VALUES); - accessStrategy.insert(new DummyEntity(ORIGINAL_ID), DummyEntity.class, Identifier.from( additionalParameters)); + accessStrategy.insert(new DummyEntity(ORIGINAL_ID), DummyEntity.class, + Identifier.from(additionalParameters)); verify(namedJdbcOperations).update(eq("INSERT INTO \"DUMMY_ENTITY\" (\"ID\") VALUES (:ID)"), paramSourceCaptor.capture(), any(KeyHolder.class)); @@ -103,13 +108,17 @@ public void additionalParametersGetAddedToStatement() { additionalParameters.put(unquoted("reference"), ID_FROM_ADDITIONAL_VALUES); - accessStrategy.insert(new DummyEntity(ORIGINAL_ID), DummyEntity.class, Identifier.from(additionalParameters)); + accessStrategy.insert(new DummyEntity(ORIGINAL_ID), DummyEntity.class, + Identifier.from(additionalParameters)); - verify(namedJdbcOperations).update(sqlCaptor.capture(), paramSourceCaptor.capture(), any(KeyHolder.class)); + verify(namedJdbcOperations).update(sqlCaptor.capture(), paramSourceCaptor.capture(), + any(KeyHolder.class)); assertThat(sqlCaptor.getValue()) // - .containsSubsequence("INSERT INTO \"DUMMY_ENTITY\" (", "\"ID\"", ") VALUES (", ":id", ")") // - .containsSubsequence("INSERT INTO \"DUMMY_ENTITY\" (", "reference", ") VALUES (", ":reference", ")"); + .containsSubsequence("INSERT INTO \"DUMMY_ENTITY\" (", "\"ID\"", ") VALUES (", + ":id", ")") // + .containsSubsequence("INSERT INTO \"DUMMY_ENTITY\" (", "reference", ") VALUES (", + ":reference", ")"); assertThat(paramSourceCaptor.getValue().getValue("id")).isEqualTo(ORIGINAL_ID); } @@ -121,7 +130,8 @@ public void considersConfiguredWriteConverter() { Dialect dialect = HsqlDbDialect.INSTANCE; JdbcConverter converter = new BasicJdbcConverter(context, relationResolver, - new JdbcCustomConversions(Arrays.asList(BooleanToStringConverter.INSTANCE, StringToBooleanConverter.INSTANCE)), + new JdbcCustomConversions(Arrays.asList(BooleanToStringConverter.INSTANCE, + StringToBooleanConverter.INSTANCE)), new DefaultJdbcTypeFactory(jdbcOperations), dialect.getIdentifierProcessing()); DefaultDataAccessStrategy accessStrategy = new DefaultDataAccessStrategy( // @@ -138,7 +148,8 @@ public void considersConfiguredWriteConverter() { accessStrategy.insert(entity, EntityWithBoolean.class, Identifier.empty()); - verify(namedJdbcOperations).update(sqlCaptor.capture(), paramSourceCaptor.capture(), any(KeyHolder.class)); + verify(namedJdbcOperations).update(sqlCaptor.capture(), paramSourceCaptor.capture(), + any(KeyHolder.class)); assertThat(paramSourceCaptor.getValue().getValue("id")).isEqualTo(ORIGINAL_ID); assertThat(paramSourceCaptor.getValue().getValue("flag")).isEqualTo("T"); @@ -170,34 +181,92 @@ public void considersConfiguredWriteConverterForIdValueObjects() { accessStrategy.insert(entity, WithValueObjectId.class, Identifier.empty()); - verify(namedJdbcOperations).update(anyString(), paramSourceCaptor.capture(), any(KeyHolder.class)); + verify(namedJdbcOperations).update(anyString(), paramSourceCaptor.capture(), + any(KeyHolder.class)); assertThat(paramSourceCaptor.getValue().getValue("id")).isEqualTo(rawId); assertThat(paramSourceCaptor.getValue().getValue("value")).isEqualTo("vs. superman"); accessStrategy.findById(new IdValue(rawId), WithValueObjectId.class); - verify(namedJdbcOperations).queryForObject(anyString(), paramSourceCaptor.capture(), any(EntityRowMapper.class)); + verify(namedJdbcOperations).queryForObject(anyString(), paramSourceCaptor.capture(), + any(EntityRowMapper.class)); assertThat(paramSourceCaptor.getValue().getValue("id")).isEqualTo(rawId); } + @Test // DATAJDBC-587 + public void considersConfiguredWriteConverterForIdValueObjectsWhichReferencedInOneToManyRelationship() { + + DelegatingDataAccessStrategy relationResolver = new DelegatingDataAccessStrategy(); + + Dialect dialect = HsqlDbDialect.INSTANCE; + + JdbcConverter converter = new BasicJdbcConverter(context, relationResolver, + new JdbcCustomConversions(Arrays.asList(IdValueToStringConverter.INSTANCE)), + new DefaultJdbcTypeFactory(jdbcOperations), dialect.getIdentifierProcessing()); + + DefaultDataAccessStrategy accessStrategy = new DefaultDataAccessStrategy( // + new SqlGeneratorSource(context, converter, dialect), // + context, // + converter, // + namedJdbcOperations); + + relationResolver.setDelegate(accessStrategy); + + String rawId = "batman"; + IdValue rootIdValue = new IdValue(rawId); + + DummyEntityRoot root = new DummyEntityRoot(rootIdValue); + DummyEntity child = new DummyEntity(ORIGINAL_ID); + root.dummyEntities.add(child); + + additionalParameters.put(SqlIdentifier.quoted("DUMMYENTITYROOT"), rootIdValue); + accessStrategy.insert(root, DummyEntityRoot.class, Identifier.from(additionalParameters)); + + verify(namedJdbcOperations).update(anyString(), paramSourceCaptor.capture(), + any(KeyHolder.class)); + + assertThat(paramSourceCaptor.getValue().getValue("id")).isEqualTo(rawId); + + PersistentPropertyPath path = + context.getPersistentPropertyPath("dummyEntities", DummyEntityRoot.class); + + accessStrategy.findAllByPath(Identifier.from(additionalParameters), path); + + verify(namedJdbcOperations).query(anyString(), paramSourceCaptor.capture(), + any(RowMapper.class)); + + assertThat(paramSourceCaptor.getValue().getValue("DUMMYENTITYROOT")).isEqualTo(rawId); + } + @RequiredArgsConstructor private static class DummyEntity { - @Id private final Long id; + @Id + private final Long id; + } + + @RequiredArgsConstructor // DATAJDBC-587 + private static class DummyEntityRoot { + + @Id + private final IdValue id; + List dummyEntities = new ArrayList<>(); } @AllArgsConstructor private static class EntityWithBoolean { - @Id Long id; + @Id + Long id; boolean flag; } @Data private static class WithValueObjectId { - @Id private final IdValue id; + @Id + private final IdValue id; String value; } From edfaf39c0975122090e7aa93f4b7c7353b48a9a6 Mon Sep 17 00:00:00 2001 From: Myat Min Date: Sun, 9 Aug 2020 13:11:55 +0800 Subject: [PATCH 3/3] Revert "DATAJDBC-587 Convert identity value object to SQL type with custom converter in FindAllByPath" This reverts commit f408369d800b975d999ee04f9a5f505740457e8e. --- .../convert/DefaultDataAccessStrategy.java | 4 +- .../DefaultDataAccessStrategyUnitTests.java | 113 ++++-------------- 2 files changed, 23 insertions(+), 94 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java index 913c391966..8b1e729f75 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategy.java @@ -367,9 +367,7 @@ private SqlParameterSource createParameterSource(Identifier identifier, Identifi SqlIdentifierParameterSource parameterSource = new SqlIdentifierParameterSource(identifierProcessing); - identifier.toMap() - .forEach((sqlIdentifier, value) -> addConvertedPropertyValue(parameterSource, - sqlIdentifier, value, value.getClass())); + identifier.toMap().forEach(parameterSource::addValue); return parameterSource; } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java index 6ae82bbfb9..42cdf12822 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java @@ -1,15 +1,17 @@ /* * Copyright 2017-2020 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 + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. + * 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.convert; @@ -22,10 +24,8 @@ import lombok.Data; import lombok.RequiredArgsConstructor; -import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.List; import lombok.Value; import org.junit.Before; @@ -37,14 +37,11 @@ import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.WritingConverter; import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; -import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.relational.core.dialect.Dialect; import org.springframework.data.relational.core.dialect.HsqlDbDialect; import org.springframework.data.relational.core.mapping.RelationalMappingContext; -import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; import org.springframework.data.relational.core.sql.SqlIdentifier; import org.springframework.jdbc.core.JdbcOperations; -import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.support.KeyHolder; @@ -66,8 +63,7 @@ public class DefaultDataAccessStrategyUnitTests { RelationalMappingContext context = new JdbcMappingContext(); HashMap additionalParameters = new HashMap<>(); - ArgumentCaptor paramSourceCaptor = - ArgumentCaptor.forClass(SqlParameterSource.class); + ArgumentCaptor paramSourceCaptor = ArgumentCaptor.forClass(SqlParameterSource.class); JdbcConverter converter; DefaultDataAccessStrategy accessStrategy; @@ -94,8 +90,7 @@ public void additionalParameterForIdDoesNotLeadToDuplicateParameters() { additionalParameters.put(SqlIdentifier.quoted("ID"), ID_FROM_ADDITIONAL_VALUES); - accessStrategy.insert(new DummyEntity(ORIGINAL_ID), DummyEntity.class, - Identifier.from(additionalParameters)); + accessStrategy.insert(new DummyEntity(ORIGINAL_ID), DummyEntity.class, Identifier.from( additionalParameters)); verify(namedJdbcOperations).update(eq("INSERT INTO \"DUMMY_ENTITY\" (\"ID\") VALUES (:ID)"), paramSourceCaptor.capture(), any(KeyHolder.class)); @@ -108,17 +103,13 @@ public void additionalParametersGetAddedToStatement() { additionalParameters.put(unquoted("reference"), ID_FROM_ADDITIONAL_VALUES); - accessStrategy.insert(new DummyEntity(ORIGINAL_ID), DummyEntity.class, - Identifier.from(additionalParameters)); + accessStrategy.insert(new DummyEntity(ORIGINAL_ID), DummyEntity.class, Identifier.from(additionalParameters)); - verify(namedJdbcOperations).update(sqlCaptor.capture(), paramSourceCaptor.capture(), - any(KeyHolder.class)); + verify(namedJdbcOperations).update(sqlCaptor.capture(), paramSourceCaptor.capture(), any(KeyHolder.class)); assertThat(sqlCaptor.getValue()) // - .containsSubsequence("INSERT INTO \"DUMMY_ENTITY\" (", "\"ID\"", ") VALUES (", - ":id", ")") // - .containsSubsequence("INSERT INTO \"DUMMY_ENTITY\" (", "reference", ") VALUES (", - ":reference", ")"); + .containsSubsequence("INSERT INTO \"DUMMY_ENTITY\" (", "\"ID\"", ") VALUES (", ":id", ")") // + .containsSubsequence("INSERT INTO \"DUMMY_ENTITY\" (", "reference", ") VALUES (", ":reference", ")"); assertThat(paramSourceCaptor.getValue().getValue("id")).isEqualTo(ORIGINAL_ID); } @@ -130,8 +121,7 @@ public void considersConfiguredWriteConverter() { Dialect dialect = HsqlDbDialect.INSTANCE; JdbcConverter converter = new BasicJdbcConverter(context, relationResolver, - new JdbcCustomConversions(Arrays.asList(BooleanToStringConverter.INSTANCE, - StringToBooleanConverter.INSTANCE)), + new JdbcCustomConversions(Arrays.asList(BooleanToStringConverter.INSTANCE, StringToBooleanConverter.INSTANCE)), new DefaultJdbcTypeFactory(jdbcOperations), dialect.getIdentifierProcessing()); DefaultDataAccessStrategy accessStrategy = new DefaultDataAccessStrategy( // @@ -148,8 +138,7 @@ public void considersConfiguredWriteConverter() { accessStrategy.insert(entity, EntityWithBoolean.class, Identifier.empty()); - verify(namedJdbcOperations).update(sqlCaptor.capture(), paramSourceCaptor.capture(), - any(KeyHolder.class)); + verify(namedJdbcOperations).update(sqlCaptor.capture(), paramSourceCaptor.capture(), any(KeyHolder.class)); assertThat(paramSourceCaptor.getValue().getValue("id")).isEqualTo(ORIGINAL_ID); assertThat(paramSourceCaptor.getValue().getValue("flag")).isEqualTo("T"); @@ -181,92 +170,34 @@ public void considersConfiguredWriteConverterForIdValueObjects() { accessStrategy.insert(entity, WithValueObjectId.class, Identifier.empty()); - verify(namedJdbcOperations).update(anyString(), paramSourceCaptor.capture(), - any(KeyHolder.class)); + verify(namedJdbcOperations).update(anyString(), paramSourceCaptor.capture(), any(KeyHolder.class)); assertThat(paramSourceCaptor.getValue().getValue("id")).isEqualTo(rawId); assertThat(paramSourceCaptor.getValue().getValue("value")).isEqualTo("vs. superman"); accessStrategy.findById(new IdValue(rawId), WithValueObjectId.class); - verify(namedJdbcOperations).queryForObject(anyString(), paramSourceCaptor.capture(), - any(EntityRowMapper.class)); + verify(namedJdbcOperations).queryForObject(anyString(), paramSourceCaptor.capture(), any(EntityRowMapper.class)); assertThat(paramSourceCaptor.getValue().getValue("id")).isEqualTo(rawId); } - @Test // DATAJDBC-587 - public void considersConfiguredWriteConverterForIdValueObjectsWhichReferencedInOneToManyRelationship() { - - DelegatingDataAccessStrategy relationResolver = new DelegatingDataAccessStrategy(); - - Dialect dialect = HsqlDbDialect.INSTANCE; - - JdbcConverter converter = new BasicJdbcConverter(context, relationResolver, - new JdbcCustomConversions(Arrays.asList(IdValueToStringConverter.INSTANCE)), - new DefaultJdbcTypeFactory(jdbcOperations), dialect.getIdentifierProcessing()); - - DefaultDataAccessStrategy accessStrategy = new DefaultDataAccessStrategy( // - new SqlGeneratorSource(context, converter, dialect), // - context, // - converter, // - namedJdbcOperations); - - relationResolver.setDelegate(accessStrategy); - - String rawId = "batman"; - IdValue rootIdValue = new IdValue(rawId); - - DummyEntityRoot root = new DummyEntityRoot(rootIdValue); - DummyEntity child = new DummyEntity(ORIGINAL_ID); - root.dummyEntities.add(child); - - additionalParameters.put(SqlIdentifier.quoted("DUMMYENTITYROOT"), rootIdValue); - accessStrategy.insert(root, DummyEntityRoot.class, Identifier.from(additionalParameters)); - - verify(namedJdbcOperations).update(anyString(), paramSourceCaptor.capture(), - any(KeyHolder.class)); - - assertThat(paramSourceCaptor.getValue().getValue("id")).isEqualTo(rawId); - - PersistentPropertyPath path = - context.getPersistentPropertyPath("dummyEntities", DummyEntityRoot.class); - - accessStrategy.findAllByPath(Identifier.from(additionalParameters), path); - - verify(namedJdbcOperations).query(anyString(), paramSourceCaptor.capture(), - any(RowMapper.class)); - - assertThat(paramSourceCaptor.getValue().getValue("DUMMYENTITYROOT")).isEqualTo(rawId); - } - @RequiredArgsConstructor private static class DummyEntity { - @Id - private final Long id; - } - - @RequiredArgsConstructor // DATAJDBC-587 - private static class DummyEntityRoot { - - @Id - private final IdValue id; - List dummyEntities = new ArrayList<>(); + @Id private final Long id; } @AllArgsConstructor private static class EntityWithBoolean { - @Id - Long id; + @Id Long id; boolean flag; } @Data private static class WithValueObjectId { - @Id - private final IdValue id; + @Id private final IdValue id; String value; }