From 6e60ab4c02ad2224d3a975e5d3894689bc9157ff Mon Sep 17 00:00:00 2001
From: Jens Schauder <jens.schauder@broadcom.com>
Date: Thu, 4 Jul 2024 16:09:50 +0200
Subject: [PATCH 01/10] 1828-aggregate-ref-with-convertable - Prepare branch

---
 pom.xml                               | 2 +-
 spring-data-jdbc-distribution/pom.xml | 2 +-
 spring-data-jdbc/pom.xml              | 4 ++--
 spring-data-r2dbc/pom.xml             | 4 ++--
 spring-data-relational/pom.xml        | 4 ++--
 5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/pom.xml b/pom.xml
index 4ecb4c4709..edb5da9d43 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
 
 	<groupId>org.springframework.data</groupId>
 	<artifactId>spring-data-relational-parent</artifactId>
-	<version>3.5.0-SNAPSHOT</version>
+	<version>3.5.0-1828-aggregate-ref-with-convertable-SNAPSHOT</version>
 	<packaging>pom</packaging>
 
 	<name>Spring Data Relational Parent</name>
diff --git a/spring-data-jdbc-distribution/pom.xml b/spring-data-jdbc-distribution/pom.xml
index 9c02f50608..f21b2f346f 100644
--- a/spring-data-jdbc-distribution/pom.xml
+++ b/spring-data-jdbc-distribution/pom.xml
@@ -14,7 +14,7 @@
 	<parent>
 		<groupId>org.springframework.data</groupId>
 		<artifactId>spring-data-relational-parent</artifactId>
-		<version>3.5.0-SNAPSHOT</version>
+		<version>3.5.0-1828-aggregate-ref-with-convertable-SNAPSHOT</version>
 		<relativePath>../pom.xml</relativePath>
 	</parent>
 
diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml
index 73b1d2f7a0..63923832fc 100644
--- a/spring-data-jdbc/pom.xml
+++ b/spring-data-jdbc/pom.xml
@@ -6,7 +6,7 @@
 	<modelVersion>4.0.0</modelVersion>
 
 	<artifactId>spring-data-jdbc</artifactId>
-	<version>3.5.0-SNAPSHOT</version>
+	<version>3.5.0-1828-aggregate-ref-with-convertable-SNAPSHOT</version>
 
 	<name>Spring Data JDBC</name>
 	<description>Spring Data module for JDBC repositories.</description>
@@ -15,7 +15,7 @@
 	<parent>
 		<groupId>org.springframework.data</groupId>
 		<artifactId>spring-data-relational-parent</artifactId>
-		<version>3.5.0-SNAPSHOT</version>
+		<version>3.5.0-1828-aggregate-ref-with-convertable-SNAPSHOT</version>
 	</parent>
 
 	<properties>
diff --git a/spring-data-r2dbc/pom.xml b/spring-data-r2dbc/pom.xml
index fd450fd21b..3dd41145ec 100644
--- a/spring-data-r2dbc/pom.xml
+++ b/spring-data-r2dbc/pom.xml
@@ -6,7 +6,7 @@
 	<modelVersion>4.0.0</modelVersion>
 
 	<artifactId>spring-data-r2dbc</artifactId>
-	<version>3.5.0-SNAPSHOT</version>
+	<version>3.5.0-1828-aggregate-ref-with-convertable-SNAPSHOT</version>
 
 	<name>Spring Data R2DBC</name>
 	<description>Spring Data module for R2DBC</description>
@@ -15,7 +15,7 @@
 	<parent>
 		<groupId>org.springframework.data</groupId>
 		<artifactId>spring-data-relational-parent</artifactId>
-		<version>3.5.0-SNAPSHOT</version>
+		<version>3.5.0-1828-aggregate-ref-with-convertable-SNAPSHOT</version>
 	</parent>
 
 	<properties>
diff --git a/spring-data-relational/pom.xml b/spring-data-relational/pom.xml
index 9760a0f1e7..dc1b955700 100644
--- a/spring-data-relational/pom.xml
+++ b/spring-data-relational/pom.xml
@@ -6,7 +6,7 @@
 	<modelVersion>4.0.0</modelVersion>
 
 	<artifactId>spring-data-relational</artifactId>
-	<version>3.5.0-SNAPSHOT</version>
+	<version>3.5.0-1828-aggregate-ref-with-convertable-SNAPSHOT</version>
 
 	<name>Spring Data Relational</name>
 	<description>Spring Data Relational support</description>
@@ -14,7 +14,7 @@
 	<parent>
 		<groupId>org.springframework.data</groupId>
 		<artifactId>spring-data-relational-parent</artifactId>
-		<version>3.5.0-SNAPSHOT</version>
+		<version>3.5.0-1828-aggregate-ref-with-convertable-SNAPSHOT</version>
 	</parent>
 
 	<properties>

From 9d4d2729dfc482beacbef863c5047f1f3e786f70 Mon Sep 17 00:00:00 2001
From: Jens Schauder <jens.schauder@broadcom.com>
Date: Thu, 4 Jul 2024 16:43:19 +0200
Subject: [PATCH 02/10] probably reproduced the issue in test

---
 ...oryCrossAggregateHsqlIntegrationTests.java | 67 ++++++++++++++++++-
 ...rossAggregateHsqlIntegrationTests-hsql.sql |  7 ++
 2 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCrossAggregateHsqlIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCrossAggregateHsqlIntegrationTests.java
index 8fcc7c132e..6e740f5250 100644
--- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCrossAggregateHsqlIntegrationTests.java
+++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryCrossAggregateHsqlIntegrationTests.java
@@ -15,26 +15,38 @@
  */
 package org.springframework.data.jdbc.repository;
 
+import static java.util.Arrays.*;
 import static org.assertj.core.api.Assertions.*;
 
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.FilterType;
 import org.springframework.context.annotation.Import;
+import org.springframework.core.convert.converter.Converter;
 import org.springframework.data.annotation.Id;
+import org.springframework.data.convert.CustomConversions;
+import org.springframework.data.convert.ReadingConverter;
+import org.springframework.data.convert.WritingConverter;
+import org.springframework.data.jdbc.core.convert.JdbcCustomConversions;
 import org.springframework.data.jdbc.core.mapping.AggregateReference;
+import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes;
 import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
 import org.springframework.data.jdbc.testing.DatabaseType;
 import org.springframework.data.jdbc.testing.EnabledOnDatabase;
 import org.springframework.data.jdbc.testing.IntegrationTest;
 import org.springframework.data.jdbc.testing.TestConfiguration;
+import org.springframework.data.mapping.model.SimpleTypeHolder;
+import org.springframework.data.relational.core.dialect.Dialect;
 import org.springframework.data.relational.core.mapping.RelationalMappingContext;
 import org.springframework.data.repository.CrudRepository;
 import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 import org.springframework.test.jdbc.JdbcTestUtils;
 
+import java.util.Collections;
+
 /**
  * Very simple use cases for creation and usage of JdbcRepositories.
  *
@@ -52,13 +64,18 @@ public class JdbcRepositoryCrossAggregateHsqlIntegrationTests {
 	@Configuration
 	@Import(TestConfiguration.class)
 	@EnableJdbcRepositories(considerNestedRepositories = true,
-			includeFilters = @ComponentScan.Filter(value = Ones.class, type = FilterType.ASSIGNABLE_TYPE))
+			includeFilters = @ComponentScan.Filter(value = {Ones.class, ReferencingAggregateRepository.class}, type = FilterType.ASSIGNABLE_TYPE))
 	static class Config {
 
+		@Bean
+		JdbcCustomConversions jdbcCustomConversions() {
+			return new JdbcCustomConversions(asList( AggregateIdToLong.INSTANCE, LongToAggregateId.INSTANCE ));
+		}
 	}
 
 	@Autowired NamedParameterJdbcTemplate template;
 	@Autowired Ones ones;
+	@Autowired ReferencingAggregateRepository referencingAggregates;
 	@Autowired RelationalMappingContext context;
 
 	@SuppressWarnings("ConstantConditions")
@@ -95,6 +112,18 @@ public void savesAndUpdate() {
 		).isEqualTo(1);
 	}
 
+	@Test // DATAJDBC-221
+	public void savesAndReadWithConvertableId() {
+
+
+		AggregateReference<AggregateWithConvertableId, AggregateId> idReference = AggregateReference.to(new AggregateId(TWO_ID));
+		ReferencingAggregate reference = referencingAggregates.save(new ReferencingAggregate(null, "Reference", idReference));
+
+
+		ReferencingAggregate reloaded = referencingAggregates.findById(reference.id).get();
+		assertThat(reloaded.id()).isEqualTo(idReference);
+	}
+
 	interface Ones extends CrudRepository<AggregateOne, Long> {}
 
 	static class AggregateOne {
@@ -109,4 +138,40 @@ static class AggregateTwo {
 		@Id Long id;
 		String name;
 	}
+
+	interface ReferencingAggregateRepository extends CrudRepository<ReferencingAggregate, Long> {
+
+	}
+
+	record AggregateWithConvertableId(@Id AggregateId id, String name) {
+
+	}
+
+	record AggregateId(Long value) {
+
+	}
+
+	record ReferencingAggregate(@Id Long id, String name,
+								AggregateReference<AggregateWithConvertableId, AggregateId> ref) {
+	}
+
+	@WritingConverter
+	enum AggregateIdToLong implements Converter<AggregateId, Long> {
+		INSTANCE;
+
+		@Override
+		public Long convert(AggregateId source) {
+			return source.value;
+		}
+	}
+
+	@ReadingConverter
+	enum LongToAggregateId implements Converter< Long,AggregateId> {
+		INSTANCE;
+
+		@Override
+		public AggregateId convert(Long source) {
+			return new AggregateId(source);
+		}
+	}
 }
diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryCrossAggregateHsqlIntegrationTests-hsql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryCrossAggregateHsqlIntegrationTests-hsql.sql
index f03df7b7ea..e0a4ba3b67 100644
--- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryCrossAggregateHsqlIntegrationTests-hsql.sql
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryCrossAggregateHsqlIntegrationTests-hsql.sql
@@ -1 +1,8 @@
 CREATE TABLE aggregate_one ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, NAME VARCHAR(100), two INTEGER);
+
+CREATE TABLE REFERENCING_AGGREGATE
+(
+    ID   BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY,
+    NAME VARCHAR(100),
+    REF  INTEGER
+);

From 5423856bef1505a137d3533c23c581045d64499b Mon Sep 17 00:00:00 2001
From: Jens Schauder <jens.schauder@broadcom.com>
Date: Fri, 5 Jul 2024 11:31:30 +0200
Subject: [PATCH 03/10] added unit test for the problem

---
 .../MappingJdbcConverterUnitTests.java        | 60 +++++++++++++------
 1 file changed, 43 insertions(+), 17 deletions(-)

diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverterUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverterUnitTests.java
index d20ea64d66..ba9bb39e38 100644
--- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverterUnitTests.java
+++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverterUnitTests.java
@@ -15,6 +15,7 @@
  */
 package org.springframework.data.jdbc.core.convert;
 
+import static java.util.Arrays.*;
 import static org.assertj.core.api.Assertions.*;
 import static org.assertj.core.api.SoftAssertions.*;
 import static org.mockito.Mockito.*;
@@ -40,6 +41,7 @@
 import org.junit.jupiter.api.Test;
 import org.springframework.core.convert.converter.Converter;
 import org.springframework.data.annotation.Id;
+import org.springframework.data.convert.WritingConverter;
 import org.springframework.data.jdbc.core.mapping.AggregateReference;
 import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
 import org.springframework.data.jdbc.core.mapping.JdbcValue;
@@ -70,7 +72,7 @@ class MappingJdbcConverterUnitTests {
 			(identifier, path) -> {
 				throw new UnsupportedOperationException();
 			}, //
-			new JdbcCustomConversions(), //
+			new JdbcCustomConversions(List.of(CustomIdToLong.INSTANCE)), //
 			typeFactory //
 	);
 
@@ -91,6 +93,9 @@ void testTargetTypesForPropertyType() {
 		checkTargetType(softly, entity, "date", Date.class);
 		checkTargetType(softly, entity, "timestamp", Timestamp.class);
 		checkTargetType(softly, entity, "uuid", UUID.class);
+		checkTargetType(softly, entity, "reference", Long.class);
+		checkTargetType(softly, entity, "enumIdReference", String.class);
+		checkTargetType(softly, entity, "customIdReference", Long.class);
 
 		softly.assertAll();
 	}
@@ -216,22 +221,21 @@ private void checkTargetType(SoftAssertions softly, RelationalPersistentEntity<?
 	}
 
 	@SuppressWarnings("unused")
-	private static class DummyEntity {
-
-		@Id private final Long id;
-		private final SomeEnum someEnum;
-		private final LocalDateTime localDateTime;
-		private final LocalDate localDate;
-		private final LocalTime localTime;
-		private final ZonedDateTime zonedDateTime;
-		private final OffsetDateTime offsetDateTime;
-		private final Instant instant;
-		private final Date date;
-		private final Timestamp timestamp;
-		private final AggregateReference<DummyEntity, Long> reference;
-		private final UUID uuid;
-		private final AggregateReference<ReferencedByUuid, UUID> uuidRef;
-		private final Optional<UUID> optionalUuid;
+	private record DummyEntity(
+			@Id Long id,
+			SomeEnum someEnum,
+			LocalDateTime localDateTime,
+			LocalDate localDate,
+			LocalTime localTime,
+			ZonedDateTime zonedDateTime,
+			OffsetDateTime offsetDateTime,
+			Instant instant,
+			Date date,
+			Timestamp timestamp,
+			AggregateReference<DummyEntity, Long> reference,
+			UUID uuid,
+			AggregateReference<ReferencedByUuid, UUID> uuidRef,
+			Optional<UUID> optionalUuid,
 
 		// DATAJDBC-259
 		private final List<String> listOfString;
@@ -337,6 +341,18 @@ private enum SomeEnum {
 	@SuppressWarnings("unused")
 	private static class OtherEntity {}
 
+	private static class EnumIdEntity {
+		@Id SomeEnum id;
+	}
+
+	private static class CustomIdEntity {
+		@Id CustomId id;
+	}
+
+	private record CustomId(Long id) {
+
+	}
+
 	private static class StubbedJdbcTypeFactory implements JdbcTypeFactory {
 		Object[] arraySource;
 
@@ -366,4 +382,14 @@ public UUID convert(byte[] source) {
 			return new UUID(high, low);
 		}
 	}
+
+	@WritingConverter
+	private enum CustomIdToLong implements Converter<CustomId, Long> {
+		INSTANCE;
+
+		@Override
+		public Long convert(CustomId source) {
+			return source.id;
+		}
+	}
 }

From 2f18a246f4da40f040e24e3804fb7a45e6725b30 Mon Sep 17 00:00:00 2001
From: Jens Schauder <jens.schauder@broadcom.com>
Date: Fri, 5 Jul 2024 13:31:07 +0200
Subject: [PATCH 04/10] fix the type holder, still doesn't resolve the issue

---
 .../data/jdbc/core/convert/MappingJdbcConverterUnitTests.java  | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverterUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverterUnitTests.java
index ba9bb39e38..dbede97e39 100644
--- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverterUnitTests.java
+++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverterUnitTests.java
@@ -75,6 +75,9 @@ class MappingJdbcConverterUnitTests {
 			new JdbcCustomConversions(List.of(CustomIdToLong.INSTANCE)), //
 			typeFactory //
 	);
+	{
+		context.setSimpleTypeHolder(converter.getConversions().getSimpleTypeHolder());
+	}
 
 	@Test // DATAJDBC-104, DATAJDBC-1384
 	void testTargetTypesForPropertyType() {

From 462380aac87ae25fa07100ed69ca24048c0f95fd Mon Sep 17 00:00:00 2001
From: Jens Schauder <jens.schauder@broadcom.com>
Date: Fri, 5 Jul 2024 13:48:32 +0200
Subject: [PATCH 05/10] fix the integration test

---
 .../relational/core/conversion/MappingRelationalConverter.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java
index c7a07679fa..73a598e87d 100644
--- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java
+++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java
@@ -690,7 +690,7 @@ public Object writeValue(@Nullable Object value, TypeInformation<?> type) {
 					: getConversions().getCustomWriteTarget(type.getType());
 
 			if (customWriteTarget.isPresent()) {
-				return getConversionService().convert(value, customWriteTarget.get());
+				return getPotentiallyConvertedSimpleWrite(getConversionService().convert(value, customWriteTarget.get()));
 			}
 
 			if (TypeInformation.OBJECT != type) {

From 1c15a9a299ce3cddcb2eddff24125e2f3a2f9393 Mon Sep 17 00:00:00 2001
From: Jens Schauder <jens.schauder@broadcom.com>
Date: Thu, 4 Jul 2024 16:12:02 +0200
Subject: [PATCH 06/10] Polishing

---
 ...ferenceTest.java => IdOnlyAggregateReferenceUnitTests.java} | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
 rename spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/{IdOnlyAggregateReferenceTest.java => IdOnlyAggregateReferenceUnitTests.java} (94%)

diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/IdOnlyAggregateReferenceTest.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/IdOnlyAggregateReferenceUnitTests.java
similarity index 94%
rename from spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/IdOnlyAggregateReferenceTest.java
rename to spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/IdOnlyAggregateReferenceUnitTests.java
index 5c224edfb8..7469d942e4 100644
--- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/IdOnlyAggregateReferenceTest.java
+++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/mapping/IdOnlyAggregateReferenceUnitTests.java
@@ -9,8 +9,9 @@
  * Unit tests for the {@link IdOnlyAggregateReference}.
  *
  * @author Myeonghyeon Lee
+ * @author Jens Schauder
  */
-public class IdOnlyAggregateReferenceTest {
+public class IdOnlyAggregateReferenceUnitTests {
 
 	@Test // DATAJDBC-427
 	public void equals() {

From e7a38b6fa44219c99f26888ded0a2e2ea6798792 Mon Sep 17 00:00:00 2001
From: Jens Schauder <jens.schauder@broadcom.com>
Date: Thu, 4 Jul 2024 16:23:38 +0200
Subject: [PATCH 07/10] Polishing

---
 ...bcRepositoryCrossAggregateHsqlIntegrationTests-hsql.sql | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryCrossAggregateHsqlIntegrationTests-hsql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryCrossAggregateHsqlIntegrationTests-hsql.sql
index e0a4ba3b67..ea1da7181f 100644
--- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryCrossAggregateHsqlIntegrationTests-hsql.sql
+++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryCrossAggregateHsqlIntegrationTests-hsql.sql
@@ -1,4 +1,9 @@
-CREATE TABLE aggregate_one ( id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, NAME VARCHAR(100), two INTEGER);
+CREATE TABLE AGGREGATE_ONE
+(
+    ID   BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY,
+    NAME VARCHAR(100),
+    TWO  INTEGER
+);
 
 CREATE TABLE REFERENCING_AGGREGATE
 (

From 7cf3bc9b5b92a226d34f5a53181d30b001b9dc80 Mon Sep 17 00:00:00 2001
From: Jens Schauder <jens.schauder@broadcom.com>
Date: Thu, 4 Jul 2024 16:57:54 +0200
Subject: [PATCH 08/10] polishing

---
 .../core/conversion/MappingRelationalConverter.java           | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java
index 73a598e87d..eb91c2d34a 100644
--- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java
+++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java
@@ -731,9 +731,7 @@ public Object writeValue(@Nullable Object value, TypeInformation<?> type) {
 			}
 		}
 
-		return
-
-		getConversionService().convert(value, type.getType());
+		return getConversionService().convert(value, type.getType());
 	}
 
 	private Object writeArray(Object value, TypeInformation<?> type) {

From 88a7e1246fb5bd706fa2063ec0e2a07b317c5737 Mon Sep 17 00:00:00 2001
From: Jens Schauder <jens.schauder@broadcom.com>
Date: Fri, 5 Jul 2024 11:19:57 +0200
Subject: [PATCH 09/10] Polishing.

Simplifying test code
---
 .../MappingJdbcConverterUnitTests.java        | 177 +++++-------------
 1 file changed, 48 insertions(+), 129 deletions(-)

diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverterUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverterUnitTests.java
index dbede97e39..c1b57482d8 100644
--- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverterUnitTests.java
+++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverterUnitTests.java
@@ -61,9 +61,9 @@
 class MappingJdbcConverterUnitTests {
 
 	private static final UUID UUID = java.util.UUID.fromString("87a48aa8-a071-705e-54a9-e52fe3a012f1");
-	private static final byte[] BYTES_REPRESENTING_UUID = { -121, -92, -118, -88, -96, 113, 112, 94, 84, -87, -27, 47,
+	private static final byte[] BYTES_REPRESENTING_UUID = {-121, -92, -118, -88, -96, 113, 112, 94, 84, -87, -27, 47,
 			-29,
-			-96, 18, -15 };
+			-96, 18, -15};
 
 	private JdbcMappingContext context = new JdbcMappingContext();
 	private StubbedJdbcTypeFactory typeFactory = new StubbedJdbcTypeFactory();
@@ -79,31 +79,32 @@ class MappingJdbcConverterUnitTests {
 		context.setSimpleTypeHolder(converter.getConversions().getSimpleTypeHolder());
 	}
 
-	@Test // DATAJDBC-104, DATAJDBC-1384
+	@Test
+		// DATAJDBC-104, DATAJDBC-1384
 	void testTargetTypesForPropertyType() {
 
 		RelationalPersistentEntity<?> entity = context.getRequiredPersistentEntity(DummyEntity.class);
 
-		SoftAssertions softly = new SoftAssertions();
-
-		checkTargetType(softly, entity, "someEnum", String.class);
-		checkTargetType(softly, entity, "localDateTime", LocalDateTime.class);
-		checkTargetType(softly, entity, "localDate", Timestamp.class);
-		checkTargetType(softly, entity, "localTime", Timestamp.class);
-		checkTargetType(softly, entity, "zonedDateTime", String.class);
-		checkTargetType(softly, entity, "offsetDateTime", OffsetDateTime.class);
-		checkTargetType(softly, entity, "instant", Timestamp.class);
-		checkTargetType(softly, entity, "date", Date.class);
-		checkTargetType(softly, entity, "timestamp", Timestamp.class);
-		checkTargetType(softly, entity, "uuid", UUID.class);
-		checkTargetType(softly, entity, "reference", Long.class);
-		checkTargetType(softly, entity, "enumIdReference", String.class);
-		checkTargetType(softly, entity, "customIdReference", Long.class);
-
-		softly.assertAll();
+		SoftAssertions.assertSoftly(softly -> {
+
+			checkTargetType(softly, entity, "someEnum", String.class);
+			checkTargetType(softly, entity, "localDateTime", LocalDateTime.class);
+			checkTargetType(softly, entity, "localDate", Timestamp.class);
+			checkTargetType(softly, entity, "localTime", Timestamp.class);
+			checkTargetType(softly, entity, "zonedDateTime", String.class);
+			checkTargetType(softly, entity, "offsetDateTime", OffsetDateTime.class);
+			checkTargetType(softly, entity, "instant", Timestamp.class);
+			checkTargetType(softly, entity, "date", Date.class);
+			checkTargetType(softly, entity, "timestamp", Timestamp.class);
+			checkTargetType(softly, entity, "uuid", UUID.class);
+			checkTargetType(softly, entity, "reference", Long.class);
+			checkTargetType(softly, entity, "enumIdReference", String.class);
+			checkTargetType(softly, entity, "customIdReference", Long.class);
+		});
 	}
 
-	@Test // DATAJDBC-259
+	@Test
+		// DATAJDBC-259
 	void classificationOfCollectionLikeProperties() {
 
 		RelationalPersistentEntity<?> entity = context.getRequiredPersistentEntity(DummyEntity.class);
@@ -119,22 +120,24 @@ void classificationOfCollectionLikeProperties() {
 		softly.assertAll();
 	}
 
-	@Test // DATAJDBC-221
+	@Test
+		// DATAJDBC-221
 	void referencesAreNotEntitiesAndGetStoredAsTheirId() {
 
 		RelationalPersistentEntity<?> entity = context.getRequiredPersistentEntity(DummyEntity.class);
 
-		SoftAssertions softly = new SoftAssertions();
 
 		RelationalPersistentProperty reference = entity.getRequiredPersistentProperty("reference");
 
-		softly.assertThat(reference.isEntity()).isFalse();
-		softly.assertThat(converter.getColumnType(reference)).isEqualTo(Long.class);
+		SoftAssertions.assertSoftly(softly -> {
 
-		softly.assertAll();
+			softly.assertThat(reference.isEntity()).isFalse();
+			softly.assertThat(converter.getColumnType(reference)).isEqualTo(Long.class);
+		});
 	}
 
-	@Test // DATAJDBC-637
+	@Test
+		// DATAJDBC-637
 	void conversionOfDateLikeValueAndBackYieldsOriginalValue() {
 
 		RelationalPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DummyEntity.class);
@@ -150,17 +153,19 @@ void conversionOfDateLikeValueAndBackYieldsOriginalValue() {
 
 	}
 
-	@Test // GH-945
+	@Test
+		// GH-945
 	void conversionOfPrimitiveArrays() {
 
-		int[] ints = { 1, 2, 3, 4, 5 };
+		int[] ints = {1, 2, 3, 4, 5};
 		JdbcValue converted = converter.writeJdbcValue(ints, ints.getClass(), JdbcUtil.targetSqlTypeFor(ints.getClass()));
 
 		assertThat(converted.getValue()).isInstanceOf(Array.class);
 		assertThat(typeFactory.arraySource).containsExactly(1, 2, 3, 4, 5);
 	}
 
-	@Test // GH-1684
+	@Test
+		// GH-1684
 	void accessesCorrectValuesForOneToOneRelationshipWithIdenticallyNamedIdProperties() {
 
 		RowDocument rowdocument = new RowDocument(Map.of("ID", "one", "REFERENCED_ID", 23));
@@ -170,7 +175,8 @@ void accessesCorrectValuesForOneToOneRelationshipWithIdenticallyNamedIdPropertie
 		assertThat(result).isEqualTo(new WithOneToOne("one", new Referenced(23L)));
 	}
 
-	@Test // GH-1750
+	@Test
+		// GH-1750
 	void readByteArrayToNestedUuidWithCustomConverter() {
 
 		JdbcMappingContext context = new JdbcMappingContext();
@@ -194,7 +200,7 @@ void readByteArrayToNestedUuidWithCustomConverter() {
 	}
 
 	private static void checkReadConversion(SoftAssertions softly, MappingJdbcConverter converter, String propertyName,
-			Object expected) {
+											Object expected) {
 
 		RelationalPersistentProperty property = converter.getMappingContext().getRequiredPersistentEntity(DummyEntity.class)
 				.getRequiredPersistentProperty(propertyName);
@@ -205,7 +211,7 @@ private static void checkReadConversion(SoftAssertions softly, MappingJdbcConver
 	}
 
 	private void checkConversionToTimestampAndBack(SoftAssertions softly, RelationalPersistentEntity<?> persistentEntity,
-			String propertyName, Object value) {
+												   String propertyName, Object value) {
 
 		RelationalPersistentProperty property = persistentEntity.getRequiredPersistentProperty(propertyName);
 
@@ -216,7 +222,7 @@ private void checkConversionToTimestampAndBack(SoftAssertions softly, Relational
 	}
 
 	private void checkTargetType(SoftAssertions softly, RelationalPersistentEntity<?> persistentEntity,
-			String propertyName, Class<?> expected) {
+								 String propertyName, Class<?> expected) {
 
 		RelationalPersistentProperty property = persistentEntity.getRequiredPersistentProperty(propertyName);
 
@@ -240,100 +246,12 @@ private record DummyEntity(
 			AggregateReference<ReferencedByUuid, UUID> uuidRef,
 			Optional<UUID> optionalUuid,
 
-		// DATAJDBC-259
-		private final List<String> listOfString;
-		private final String[] arrayOfString;
-		private final List<OtherEntity> listOfEntity;
-		private final OtherEntity[] arrayOfEntity;
-
-		private DummyEntity(Long id, SomeEnum someEnum, LocalDateTime localDateTime, LocalDate localDate,
-							LocalTime localTime, ZonedDateTime zonedDateTime, OffsetDateTime offsetDateTime, Instant instant, Date date,
-							Timestamp timestamp, AggregateReference<DummyEntity, Long> reference, UUID uuid,
-							AggregateReference<ReferencedByUuid, UUID> uuidRef, Optional<java.util.UUID> optionalUUID, List<String> listOfString, String[] arrayOfString,
-							List<OtherEntity> listOfEntity, OtherEntity[] arrayOfEntity) {
-			this.id = id;
-			this.someEnum = someEnum;
-			this.localDateTime = localDateTime;
-			this.localDate = localDate;
-			this.localTime = localTime;
-			this.zonedDateTime = zonedDateTime;
-			this.offsetDateTime = offsetDateTime;
-			this.instant = instant;
-			this.date = date;
-			this.timestamp = timestamp;
-			this.reference = reference;
-			this.uuid = uuid;
-			this.uuidRef = uuidRef;
-			this.optionalUuid = optionalUUID;
-			this.listOfString = listOfString;
-			this.arrayOfString = arrayOfString;
-			this.listOfEntity = listOfEntity;
-			this.arrayOfEntity = arrayOfEntity;
-		}
-
-		public Long getId() {
-			return this.id;
-		}
-
-		public SomeEnum getSomeEnum() {
-			return this.someEnum;
-		}
-
-		public LocalDateTime getLocalDateTime() {
-			return this.localDateTime;
-		}
-
-		public LocalDate getLocalDate() {
-			return this.localDate;
-		}
-
-		public LocalTime getLocalTime() {
-			return this.localTime;
-		}
-
-		public ZonedDateTime getZonedDateTime() {
-			return this.zonedDateTime;
-		}
-
-		public OffsetDateTime getOffsetDateTime() {
-			return this.offsetDateTime;
-		}
-
-		public Instant getInstant() {
-			return this.instant;
-		}
-
-		public Date getDate() {
-			return this.date;
-		}
-
-		public Timestamp getTimestamp() {
-			return this.timestamp;
-		}
-
-		public AggregateReference<DummyEntity, Long> getReference() {
-			return this.reference;
-		}
-
-		public UUID getUuid() {
-			return this.uuid;
-		}
-
-		public List<String> getListOfString() {
-			return this.listOfString;
-		}
-
-		public String[] getArrayOfString() {
-			return this.arrayOfString;
-		}
-
-		public List<OtherEntity> getListOfEntity() {
-			return this.listOfEntity;
-		}
-
-		public OtherEntity[] getArrayOfEntity() {
-			return this.arrayOfEntity;
-		}
+			// DATAJDBC-259
+			List<String> listOfString,
+			String[] arrayOfString,
+			List<OtherEntity> listOfEntity,
+			OtherEntity[] arrayOfEntity
+	) {
 	}
 
 	@SuppressWarnings("unused")
@@ -342,7 +260,8 @@ private enum SomeEnum {
 	}
 
 	@SuppressWarnings("unused")
-	private static class OtherEntity {}
+	private static class OtherEntity {
+	}
 
 	private static class EnumIdEntity {
 		@Id SomeEnum id;

From 531171ed0b34c6bcd945de639dc2aef2c5ea2d49 Mon Sep 17 00:00:00 2001
From: Jens Schauder <jens.schauder@broadcom.com>
Date: Wed, 6 Nov 2024 09:46:56 +0100
Subject: [PATCH 10/10] polishing

---
 .../core/conversion/MappingRelationalConverter.java          | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java
index eb91c2d34a..a2b2dbe3c4 100644
--- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java
+++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/conversion/MappingRelationalConverter.java
@@ -722,13 +722,10 @@ public Object writeValue(@Nullable Object value, TypeInformation<?> type) {
 
 		if (getMappingContext().hasPersistentEntityFor(value.getClass())) {
 
-			RelationalPersistentEntity<?> persistentEntity = getMappingContext().getPersistentEntity(value.getClass());
-
-			if (persistentEntity != null) {
+			RelationalPersistentEntity<?> persistentEntity = getMappingContext().getRequiredPersistentEntity(value.getClass());
 
 				Object id = persistentEntity.getIdentifierAccessor(value).getIdentifier();
 				return writeValue(id, type);
-			}
 		}
 
 		return getConversionService().convert(value, type.getType());