Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JPA entity listener autowired field is never injected since 2.3.7.RELEASE #27892

Closed
carmas-RatedPower opened this issue Sep 8, 2021 · 1 comment
Labels
status: invalid An issue that we don't feel is valid

Comments

@carmas-RatedPower
Copy link

In an attempt to upgrade SpringBoot from version 2.3.6.RELEASE to 2.5.4, I noticed that autowired fields are never injected, causing NullPointerException.

I have a @Entity with its @EntityListeners annotation. The listener class is annotated with @Component and has an @Autowired field that is used in a @PrePersist annotated method. This field gets injected correctly with SpringBoot version 2.3.6.RELEASE. As of 2.3.7.RELEASE this field is never injected, causing NullPointerException when accessing the field.

Find attached below two test cases to reproduce this issue.

  • Test case with SpringBoot version 2.3.6.RELEASE, with the expected behaviour:
    test_case_2.3.6.RELEASE.zip

  • Test case with SpringBoot version 2.5.4, autowired field is never injected, causing NullPointerException:
    test_case_2.5.4.zip

Additionally, I found that a very similar issue was created some time ago, but due to lack of requested information was closed.
Similar issue: #25153

Please let me know if I'm doing wrong the autowiring and the proper way to do it, or indeed this is a bug.

Kind regards.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Sep 8, 2021
@wilkinsona
Copy link
Member

Thanks for the sample.

There's a circular dependency between your entity listener (which depends, indirectly, on a Spring Data JPA repository) and the entity manager factory (which the Spring Data JPA repository depends upon). You can see this in the log output if you remove the default constructor from your listener:

***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

┌─────┐
|  entityManagerFactory defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]
↑     ↓
|  com.example.listeners.mytest.entity.DummyEntityListener
↑     ↓
|  dummyServiceImpl defined in file [/Users/awilkinson/Downloads/mytest/target/classes/com/example/listeners/mytest/service/DummyServiceImpl.class]
↑     ↓
|  dummyRepository defined in com.example.listeners.mytest.repository.DummyRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration
↑     ↓
|  (inner bean)#30ec211a
└─────┘

In Spring Boot 2.3.6, the entity manager is initialized asynchronously but this caused a number of problems and the default was changed in 2.3.7. Your application was relying upon a race between the asynchronous initialization of the entity manager and of your entity listener. If the latter wins, the problem does not occur. If the former wins, the entity listener is created as part of trying to create the entity manager which triggers the circular dependency failure.

Setting spring.data.jpa.repositories.bootstrap-mode=deferred restores 2.3.6's behaviour but it depends on a particular outcome of the race condition and is unlikely to be robust. In my opinion, a better solution would be to break the cycle more explicitly, for example by marking the injection of DummyService into the listener as @Lazy:

@Autowired
public DummyEntityListener(@Lazy DummyService dummyService) {
    this.dummyService = dummyService;
}

@wilkinsona wilkinsona added status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged labels Sep 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

3 participants