I've tried to build a minimal reproduction of the deadlock issue I mentioned in #16230, this is what I've come up with so far.

Using spring-boot-parent 2.3.3, spring-boot-starter-jpa and h2 this reliably deadlocks on startup on my machine:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.stereotype.Component;

import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.Id;
import javax.persistence.PrePersist;

@SpringBootApplication
@EnableJpaAuditing
public class DemoApplication {


    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Component
    public static class MyBean { }

}


@Entity
@EntityListeners({MyEntityListener.class})
class MyEntity {

    @Id
    private Long id;
}

class MyEntityListener {

    private final DemoApplication.MyBean myBean;

    // It's my understanding that constructor injection on entity listeners is supported, even though it's not
    // JPA compliant. Changing this to setter Injection still results in a deadlock
    public MyEntityListener(DemoApplication.MyBean myBean) {
        this.myBean = myBean;
    }

    @PrePersist
    public void prePersist(MyEntity myEntity) {
        // needs to have one annotated method otherwise it's ignored
    }
}

Suspending the thread with a break point (ie in AbstractEntityManagerFactoryBean.buildNativeEntityManager()) until the main thread is waiting on the Future should always produce it.

In my actual Service I have an EntityListener with an injected dependency as well. Wrapping the dependency in an ObjectFactory seems to remove the Deadlock there as well.

Thread Dump:

"main@1" prio=5 tid=0x1 nid=NA waiting
  java.lang.Thread.State: WAITING
     blocks task-1@4636
      at jdk.internal.misc.Unsafe.park(Unsafe.java:-1)
      at java.util.concurrent.locks.LockSupport.park(LockSupport.java:211)
      at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:447)
      at java.util.concurrent.FutureTask.get(FutureTask.java:190)
      at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.getNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:540)
      at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.invokeProxyMethod(AbstractEntityManagerFactoryBean.java:497)
      at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(AbstractEntityManagerFactoryBean.java:680)
      at com.sun.proxy.$Proxy55.getMetamodel(Unknown Source:-1)
      at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean$$Lambda$424.1048842522.apply(Unknown Source:-1)
      at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
      at java.util.Iterator.forEachRemaining(Iterator.java:133)
      at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
      at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
      at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
      at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
      at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
      at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
      at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.getMetamodels(JpaMetamodelMappingContextFactoryBean.java:106)
      at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:80)
      at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:44)
      at org.springframework.beans.factory.config.AbstractFactoryBean.afterPropertiesSet(AbstractFactoryBean.java:142)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1853)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1790)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
      at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
      at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$227.873827336.getObject(Unknown Source:-1)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
      - locked <0x16d7> (a java.util.concurrent.ConcurrentHashMap)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
      at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:330)
      at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113)
      at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:690)
      at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:196)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1356)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1203)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:556)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
      at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
      at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$227.873827336.getObject(Unknown Source:-1)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897)
      at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879)
      at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551)
      - locked <0x16d8> (a java.lang.Object)
      at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758)
      at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750)
      at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
      at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
      at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
      at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
      at com.example.demo.DemoApplication.main(DemoApplication.java:19)

"task-1@4636" prio=5 tid=0x19 nid=NA waiting for monitor entry
  java.lang.Thread.State: BLOCKED
     waiting for main@1 to release lock on <0x16d7> (a java.util.concurrent.ConcurrentHashMap)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:183)
      at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:523)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:530)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:503)
      at org.springframework.beans.factory.BeanFactoryUtils.beanNamesForTypeIncludingAncestors(BeanFactoryUtils.java:265)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1473)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1270)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1227)
      at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:884)
      at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:788)
      at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:227)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1356)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1203)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:556)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:353)
      at org.springframework.orm.hibernate5.SpringBeanContainer.createBean(SpringBeanContainer.java:147)
      at org.springframework.orm.hibernate5.SpringBeanContainer.getBean(SpringBeanContainer.java:105)
      at org.hibernate.resource.beans.internal.ManagedBeanRegistryImpl.getBean(ManagedBeanRegistryImpl.java:61)
      at org.hibernate.jpa.event.internal.CallbackBuilderLegacyImpl.resolveEntityCallbacks(CallbackBuilderLegacyImpl.java:200)
      at org.hibernate.jpa.event.internal.CallbackBuilderLegacyImpl.buildCallbacksForEntity(CallbackBuilderLegacyImpl.java:74)
      at org.hibernate.event.service.internal.EventListenerRegistryImpl.prepare(EventListenerRegistryImpl.java:146)
      at org.hibernate.boot.internal.MetadataImpl.initSessionFactory(MetadataImpl.java:379)
      at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:213)
      at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:469)
      at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259)
      at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
      at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
      at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:391)
      at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$$Lambda$423.69160933.call(Unknown Source:-1)
      at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
      at java.util.concurrent.FutureTask.run(FutureTask.java:-1)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
      at java.lang.Thread.run(Thread.java:832)

Comment From: snicoll

Thank you for the report. As I was indicated in the related issue, can you please turn that code in text into an actual project we can run?

Comment From: hgarus

@snicoll

https://github.com/hgarus/entitylistener-deadlock

Comment From: knoobie

Could this be related to https://github.com/spring-projects/spring-framework/issues/25111?

Comment From: snicoll

Sounds about right @knoobie, thank you.

@hgarus thank you for sharing a sample we can run. I'll add a note to the related issue to try out your sample once we have a fix for the framework issue.

Comment From: steklopod

Have similar issue when using gradle plugin and @AutoConfigureMockMvc

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

All @SIntegrationTest 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: dc-up42

Have this problem on 2.4.0.

Comment From: snicoll

@dc-up42 this issue is closed. If you believe you found a bug in Spring Boot, please create a separate issue. Before doing so, we'll need a small sample that reproduces the problem. You can do that by attaching a zip to the issue or sharing a link to a GitHub repository. Thank you.

Comment From: girtsivans

@hgarus You can add Lazy annotation

public MyEntityListener(@Lazy DemoApplication.MyBean myBean) {
    this.myBean = myBean;
}

Found this solution here