I'm migrating my existing Spring Boot 2.1.x application to 2.6.x. I want the following behavior (for integration tests which uses embedded H2 database), which is working fine in 2.1.x (obviously) but I'm struggling to achieve the same behavior in 2.6.x.

  1. Create DDL automatically (without any custom SQL script)
  2. Execute custom DML (data.sql)
  3. Initialize beans which implements InitializingBean and use data populated in step #2. Eg. Cache database table records for application to use later

Problem 1 (Resolved)

2.6.x was no longer created DDL automatically by default. So adding below properties explicit seemed to be the solution.

spring.jpa.generate-ddl = true
spring.jpa.hibernate.ddl-auto = create-drop

This solves Step #1 with 2.6.x.

Problem 2 (Resolved)

Starting from 2.5, Boot was running scripts in data.sql before Hibernate is initialized. Hence, data.sql was failing. To make Boot wait for DDL creation to complete, adding below property seemed to be the solution.

spring.jpa.defer-datasource-initialization = true

This solves *Step #2 with 2.6.x.

Problem 3 (NOT RESOLVED)

Seemingly because of setting spring.jpa.defer-datasource-initialization to true, Step #3 is happening before Step #2 i.e. in 2.6.x. This cause beans to initialize with empty database tables e.g. Cache is populated with no entries. These are causing my tests to fail.

I played with other properties like spring.data.jpa.repositories.bootstrap-mode and spring.sql.init.mode to workaround this without any luck.

Is this behavior I'm looking achievable at all with 2.6.x?

Comment From: philwebb

The SqlDataSourceScriptDatabaseInitializer class is responsible for applying the data.sql scripts and it itself is an InitializingBean. I suspect that Spring Framework hasn't got any ordering rules around your beans and so doesn't know that it needs to be executed first.

There are a few ways to define the depends-on relationship. You might want to try using the @DependsOn annotation on your bean method. I think that setting @DependsOn("dataSourceScriptDatabaseInitializer") on your caching beans would be enough to ensure scripts have been run.

Another, perhaps more robust way is to define a DependsOnDatabaseInitializationDetector. You can add a DependsOnDatabaseInitializationDetector entry to a spring.factories file and point to an implementation that finds beans of a particular type.

For example, we have this line in spring.factories to configure SpringJdbcDependsOnDatabaseInitializationDetector. The code for that class is here. It ensures that JdbcOperations and NamedParameterJdbcOperations beans depend on the initialization logic.

I'll close this one for now in the hope that that information is enough. If you can't get it to work, please add a sample application to this issue so we can see exactly what you're trying to do.

Comment From: rajbdilip

@philwebb The caching bean actually has a dependency on Repository of the Database table it intends to read from and hence working as expected in Boot 2.1.x.

Given that it is a migration and only tests are failing because of this, I was wondering if there was a way to achieve with just configuration changes. Making code (and dependency) changes just to satisfy tests of an otherwise fine running application feels like an overkill.

Should you still need sample application code I could attach them in the next code.

Comment From: philwebb

@rajbdilip A sample would be most helpful to really understand the issue.

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: spring-projects-issues

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.