From 210ab249e373c535796b1ff6f9ccfe1ab9c55a7b Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Tue, 26 May 2020 18:05:26 +0200 Subject: [PATCH] DATACMNS-1734 - Defer initialization of Repositories in DomainClassConverter. DomainClassConverter now delays the initialization of the Repositories instances used to avoid the premature initialization of repository instances as that can cause deadlocks if the infrastructure backing the repositories is initialized on a separate thread. Refactored nested converter classes to allow them to be static ones. Related issues: spring-projects/spring-boot#16230, spring-projects/spring-framework#25131. Original pull request: #445. --- .../support/DomainClassConverter.java | 38 ++++++++++++++----- .../DomainClassConverterUnitTests.java | 2 +- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/springframework/data/repository/support/DomainClassConverter.java b/src/main/java/org/springframework/data/repository/support/DomainClassConverter.java index 740c99de4..01080cdfb 100644 --- a/src/main/java/org/springframework/data/repository/support/DomainClassConverter.java +++ b/src/main/java/org/springframework/data/repository/support/DomainClassConverter.java @@ -30,6 +30,7 @@ import org.springframework.core.convert.converter.ConverterRegistry; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.core.EntityInformation; import org.springframework.data.repository.core.RepositoryInformation; +import org.springframework.data.util.Lazy; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -47,7 +48,7 @@ public class DomainClassConverter repositories = Lazy.of(Repositories.NONE); private Optional toEntityConverter = Optional.empty(); private Optional toIdConverter = Optional.empty(); @@ -97,7 +98,7 @@ public class DomainClassConverter getConverter(TypeDescriptor targetType) { - return repositories.hasRepositoryFor(targetType.getType()) ? toEntityConverter : toIdConverter; + return repositories.get().hasRepositoryFor(targetType.getType()) ? toEntityConverter : toIdConverter; } /* @@ -106,13 +107,18 @@ public class DomainClassConverter { - this.toEntityConverter = Optional.of(new ToEntityConverter(this.repositories, this.conversionService)); - this.toEntityConverter.ifPresent(it -> this.conversionService.addConverter(it)); + Repositories repositories = new Repositories(context); - this.toIdConverter = Optional.of(new ToIdConverter()); - this.toIdConverter.ifPresent(it -> this.conversionService.addConverter(it)); + this.toEntityConverter = Optional.of(new ToEntityConverter(repositories, conversionService)); + this.toEntityConverter.ifPresent(it -> conversionService.addConverter(it)); + + this.toIdConverter = Optional.of(new ToIdConverter(repositories, conversionService)); + this.toIdConverter.ifPresent(it -> conversionService.addConverter(it)); + + return repositories; + }); } /** @@ -121,9 +127,11 @@ public class DomainClassConverter toIdConverter = (Optional) ReflectionTestUtils.getField(converter,