Version: Spring Boot 2.3.x

Minimal example: Autowiring for instance an objectMapper into a custom AttributeConverter works fine with all versions of spring-boot v2.2.x. However, when upgrading to spring-boot 2.3.0 the objectMapper is no longer autowired and the application freezes indefinitely and doesn't start up.

Example of AttributeConverter:

@Component
public class StringListToJsonConverter implements AttributeConverter<List<String>, String> {

    private static ObjectMapper objectMapper;

    @Autowired
    public void init(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public String convertToDatabaseColumn(List<String> documentObj) {
        // Do some logic...
    }

    @Override
    public List<String> convertToEntityAttribute(String documentStr) {
        // Do some logic...
    }
}

Comment From: snicoll

Thanks for the report. It is likely to be due to JPA deferred mode. Can you please try with the latest release for a start, i.e. 2.3.5.RELEASE? If that's still broken, please share a minimal example we can actually run (rather that code in text). You can do so by attaching a zip to this issue or share a link to a GitHub repository.

Comment From: Miicroo

@snicoll Tried using default as BootstrapMode, and now all beans are autowired correctly. Thank you for the help, I am closing this since their was no real issue :)

Comment From: snicoll

Thanks for letting us know but that's working around the issue. We'd like to understand if we could do something so that your use case works out-of-the-box. Can you please test your application unchanged (without the default bootstrap mode) with Spring Boot 2.3.5.RELEASE? If that still breaks, could you help us by sharing a small sample?

Comment From: steklopod

Have similar issue when using gradle plugin and @AutoConfigureMockMvc

id("org.springframework.boot") version "2.3.5.RELEASE"

All @IntegrationTest ok, but when first @WebTest test freeze and never ends.

But with 2.3.4.RELEASE - no such problem

// OK
@SpringBootTest
@Target(CLASS)
@Retention(RUNTIME)
@ActiveProfiles("test")
annotation class IntegrationTest

// Freeze (deadlock)
@Target(CLASS)
@Retention(RUNTIME)
@IntegrationTest
@AutoConfigureMockMvc
annotation class WebTest

Also in this project I'm using liquibase. No exception. Just deadlock

@WebTest
internal class UserControllerTest(@Autowired private val mockMvc: MockMvc) {
    private val baseUrl = "/user"

    @Test
    fun userTest() {
        mockMvc.perform(postWithTokenInHeader(baseUrl))
//            .andDo(MockMvcResultHandlers.print())
            .andExpect(status().isOk)
}

Comment From: wilkinsona

Thanks, @steklopod. Could you please open a new issue with a minimal sample that reproduces the problem?

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: Miicroo

@snicoll Sorry for the long delay, I have uploaded the following example (with data.jpa.repositories.bootstrap-mode: default commented out and spring-boot 2.3.5). Without bootstrap-mode: default it still hangs for med om java 11.

test-autowire-objectmapper.zip

Comment From: snicoll

Thank you very much for taking the time to share a sample @Miicroo. I've reproduced the deadlock and will look at the code in more details to see if there's a workaround or something we can change ourselves to avoid the problem.

Comment From: snicoll

So there's a number of things going on there. With deferred JPA bootstrap, you're not supposed to use the JPA infrastructure on startup but Api injects a Repository and then use it to save an object. I've moved this piece of code to a later phase using SmartInitializingSingleton and the deadlock went away.

The StringListToColumnConverter is another area of improvement. Rather than injecting the ObjectMapper upfront (which triggers a bean resolution that can lead to a lock) you could inject an ObjectProvider<ObjectMapper> and resolve the actual bean on first use only. This also removes the deadlock.

We've got a number of reports similar to yours in the recent past so I think we need to do something in our documentation to warn users what deferred JPA bootstrap entails. Let's reuse this issue for that.

Comment From: Miicroo

Thanks for the explanations, really nice to hear about how it should be done. I wrote the example just as a quick-throw-together-app, a more realistic example would be that the Api uses som service which under the hood uses a repository. Would that lead to the same problem? My guess is yes, since the only difference would be the number of beans that need to be resolved compared to the example app.

Comment From: snicoll

Thanks for the feedback.

Would that lead to the same problem? My guess is yes, since the only difference would be the number of beans that need to be resolved compared to the example app.

Yes, it doesn't matter how much hop. Using the JPA infrastructure as part of the BeanFactory bootstrap is the problem.