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

Asynchronous EntityManagerFactory bootstrapping to complete on context refresh completion [SPR-17334] #21868

Open
spring-issuemaster opened this issue Oct 4, 2018 · 2 comments

Comments

@spring-issuemaster
Copy link
Collaborator

@spring-issuemaster spring-issuemaster commented Oct 4, 2018

Andy Wilkinson opened SPR-17334 and commented

When a LocalEntityManagerFactory bean is configured with a bootstrap executor, there's a race between application context refresh and native entity manager factory bootstrapping. This makes things awkward for any logic that wants to run once bootstrapping has completed, for example something that relies on Hibernate DDL processing.

I've attached a small example that hopefully illustrates the problem. When imported into your IDE and run, EmfBootstrappingRaceApplication should thrown an exception when executing the SELECT query using JdbcTemplate. The failure will not occur if factory.setBootstrapExecutor(executor); is commented out. The failure will occur intermittently if the artificial delay introduced by the async executor is removed.


Affects: 4.3.19, 5.0.9, 5.1 GA

Reference URL: spring-projects/spring-boot#14658

Attachments:

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Oct 4, 2018

Juergen Hoeller commented

This is meant to be by design: The application and its web endpoints can be up and listening already while the persistence provider is still bootstrapping, only blocking once a request comes in that actually needs to access the persistence provider.

That said, I can see the issue with post-bootstrapping logic here. I guess we could try to attach a callback to the async bootstrap thread there, or we could have a mode of bootstrapping where we effectively wait and block at the end of the refresh phase.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Oct 4, 2018

Andy Wilkinson commented

Ah, I see. And that will of course work fine if you only access the database via the entity manager. It remains problematic for applications that aren't purely using JPA and are using JdbcTemplate, jOOQ, or whatever as well.

The area of Boot that led me to investigate this was DataSource initialisation. Users can provide data scripts that populate the database once EntityManagerFactory bootstrapping has completed. We're currently detecting the completion of bootstrapping by decorating the JpaVendorAdapter and (ab)using the postProcessEntityManagerFactory callback. This works, but doesn't feel particularly clean. An official callback for the completion of bootstrapping would be useful.

As things stand, even with our (ab)use of the postProcessEntityManagerFactory callback, we still get into the state where refresh completes with the database in an unknown state. I think there'd definitely be benefit to an option that blocks right at the end of refresh until bootstrapping is completed. This should allow anything not going through JPA to access the database once its reached a predictable state.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.