Correct post #45: Flyway and Liquibase DO run under @DataJpaTest by default
The previous commit's FlywayDoesNotRunUnderPlainDataJpaTestTest and FlywayRunsWhenExplicitlyImportedTest rested on a false premise: that none of @DataJpaTest's four documented meta-annotations import FlywayAutoConfiguration, so migrations never run under the slice. That reading of the four .imports manifests is accurate but incomplete. @AutoConfigureJdbc is itself meta-annotated with @AutoConfigureDataSourceInitialization (new in Boot 4.0), and Spring's ImportAutoConfigurationImportSelector walks the full meta-annotation tree transitively. That fifth annotation's own .imports resource is loaded via ClassLoader.getResources(), which merges same-named files from every jar on the classpath -- spring-boot-jdbc-test, spring-boot-flyway and spring-boot-liquibase each ship one at the identical path, contributing DataSourceInitializationAutoConfiguration, FlywayAutoConfiguration and LiquibaseAutoConfiguration respectively. Replaced the two wrong-premise test classes with FlywayRunsByDefaultTest (proves the bean is present and the migration actually ran) and ExplicitFlywayImportIsRedundantTest (proves the old "add the import yourself" advice is harmless but unnecessary on Boot 4.1). Added javap/unzip evidence for the new mechanism to docs/output, re-captured the full test run (9 tests, 1 clean skip), corrected README's test table, and closed a second, unrelated gap: the unzip -l listing quoted in the @ServiceConnection section had no matching captured transcript -- it does now.
This commit is contained in:
@@ -6,9 +6,19 @@ Companion module for [`@DataJpaTest` with Testcontainers `@ServiceConnection` on
|
|||||||
|
|
||||||
Six JUnit 5 test classes against one JPA repository (`Product`), each isolating one fact about
|
Six JUnit 5 test classes against one JPA repository (`Product`), each isolating one fact about
|
||||||
what `@DataJpaTest`'s default embedded-database substitution actually does, what
|
what `@DataJpaTest`'s default embedded-database substitution actually does, what
|
||||||
`@ServiceConnection` wires in its place, and what the defaults do not do (Flyway migrations are
|
`@ServiceConnection` wires in its place, and what the defaults do run that you might not expect
|
||||||
not one of them). No `docs/NN-topic.md` chapters — everything beyond what fits in the post itself
|
(Flyway migrations, as it turns out, are one of them). No `docs/NN-topic.md` chapters —
|
||||||
is in the Javadoc on these six test classes and in the captured transcripts below.
|
everything beyond what fits in the post itself is in the Javadoc on these six test classes and in
|
||||||
|
the captured transcripts below.
|
||||||
|
|
||||||
|
**Correction, made before this module was published:** an earlier draft of two of these classes
|
||||||
|
asserted that `@DataJpaTest` never runs Flyway or Liquibase migrations, on the strength of reading
|
||||||
|
its four documented meta-annotations' `.imports` manifests and finding no mention of either tool.
|
||||||
|
That reading was accurate and incomplete — see `FlywayRunsByDefaultTest`'s Javadoc and
|
||||||
|
`docs/output/06-autoconfigurejdbc-meta-annotation-javap.txt` for the fifth, undocumented-for-this-slice
|
||||||
|
meta-annotation that actually wires them in. The two test classes below that carried the wrong
|
||||||
|
premise (`FlywayDoesNotRunUnderPlainDataJpaTestTest`, `FlywayRunsWhenExplicitlyImportedTest`) were
|
||||||
|
replaced, not patched, with `FlywayRunsByDefaultTest` and `ExplicitFlywayImportIsRedundantTest`.
|
||||||
|
|
||||||
**This module was built and tested in a sandbox with no Docker daemon available.** Five of the six
|
**This module was built and tested in a sandbox with no Docker daemon available.** Five of the six
|
||||||
test classes run and pass (or cleanly skip) without one. The sixth demonstrates, on purpose, the
|
test classes run and pass (or cleanly skip) without one. The sixth demonstrates, on purpose, the
|
||||||
@@ -29,7 +39,7 @@ the test table below for exactly which is which.
|
|||||||
## Quickstart
|
## Quickstart
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mvn test # 6 of 7 run; 1 skips cleanly
|
mvn test # 9 tests run; 1 skips cleanly
|
||||||
mvn test -Dtest=ServiceConnectionWithoutGuardFailsToStartTest # the one deliberate failure
|
mvn test -Dtest=ServiceConnectionWithoutGuardFailsToStartTest # the one deliberate failure
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -38,8 +48,8 @@ mvn test -Dtest=ServiceConnectionWithoutGuardFailsToStartTest # the one delibera
|
|||||||
| Class | What it proves | Needs Docker | Outcome here |
|
| Class | What it proves | Needs Docker | Outcome here |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `DefaultReplacementTest` | Plain `@DataJpaTest` substitutes an embedded H2 DataSource, and each test method is rolled back independently of execution order | No | Pass |
|
| `DefaultReplacementTest` | Plain `@DataJpaTest` substitutes an embedded H2 DataSource, and each test method is rolled back independently of execution order | No | Pass |
|
||||||
| `FlywayDoesNotRunUnderPlainDataJpaTestTest` | `@DataJpaTest`'s own auto-configuration import list never includes `FlywayAutoConfiguration` or `LiquibaseAutoConfiguration` — your migrations never run, substitution or not | No | Pass |
|
| `FlywayRunsByDefaultTest` | A plain `@DataJpaTest`, with flyway-core and `spring-boot-starter-flyway` on the (test) classpath, runs the real Flyway migration by default — no `@ImportAutoConfiguration` needed, because `@AutoConfigureJdbc` is itself meta-annotated with `@AutoConfigureDataSourceInitialization`, which merges contributions from every jar on the classpath that ships one | No | Pass |
|
||||||
| `FlywayRunsWhenExplicitlyImportedTest` | The one-line fix: `@ImportAutoConfiguration(FlywayAutoConfiguration.class)` | No | Pass |
|
| `ExplicitFlywayImportIsRedundantTest` | Explicitly re-adding `@ImportAutoConfiguration(FlywayAutoConfiguration.class)` — the old advice for the (incorrect) premise above — changes nothing: still exactly one `flyway` bean, still exactly one applied migration | No | Pass |
|
||||||
| `NoSubstitutionStillSilentlyUsesH2Test` | `@AutoConfigureTestDatabase(replace = Replace.NONE)` alone is not a guarantee of a real connection — with nothing else configured, ordinary `DataSourceAutoConfiguration` still silently hands you embedded H2 | No | Pass |
|
| `NoSubstitutionStillSilentlyUsesH2Test` | `@AutoConfigureTestDatabase(replace = Replace.NONE)` alone is not a guarantee of a real connection — with nothing else configured, ordinary `DataSourceAutoConfiguration` still silently hands you embedded H2 | No | Pass |
|
||||||
| `ServiceConnectionSkipsCleanlyTest` | The intended shape: `@ServiceConnection` + `@Container` + `replace = Replace.NONE`, guarded by Testcontainers 2.0's new `@EnabledIfDockerAvailable` | Yes (guarded) | Skipped |
|
| `ServiceConnectionSkipsCleanlyTest` | The intended shape: `@ServiceConnection` + `@Container` + `replace = Replace.NONE`, guarded by Testcontainers 2.0's new `@EnabledIfDockerAvailable` | Yes (guarded) | Skipped |
|
||||||
| `ServiceConnectionWithoutGuardFailsToStartTest` | The same class, minus the guard | Yes (unguarded) | **Fails — on purpose.** Excluded from `mvn test` by name in `pom.xml`; run it explicitly |
|
| `ServiceConnectionWithoutGuardFailsToStartTest` | The same class, minus the guard | Yes (unguarded) | **Fails — on purpose.** Excluded from `mvn test` by name in `pom.xml`; run it explicitly |
|
||||||
@@ -48,11 +58,12 @@ mvn test -Dtest=ServiceConnectionWithoutGuardFailsToStartTest # the one delibera
|
|||||||
|
|
||||||
| File | Contents |
|
| File | Contents |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `docs/output/00-full-test-run.txt` | `mvn clean test` — 7 tests, 1 skip, build green |
|
| `docs/output/00-full-test-run.txt` | `mvn clean test` — 9 tests, 1 skip, build green |
|
||||||
| `docs/output/01-postgresqlcontainer-relocation-javap.txt` | `javap` proof that `org.testcontainers.postgresql.PostgreSQLContainer` (2.0.5's new home) and the deprecated `org.testcontainers.containers.PostgreSQLContainer` shim live in the *same* jar, and that the old class alone keeps the self-referential `<SELF extends ...>` generic |
|
| `docs/output/01-postgresqlcontainer-relocation-javap.txt` | `javap` proof that `org.testcontainers.postgresql.PostgreSQLContainer` (2.0.5's new home) and the deprecated `org.testcontainers.containers.PostgreSQLContainer` shim live in the *same* jar, and that the old class alone keeps the self-referential `<SELF extends ...>` generic |
|
||||||
| `docs/output/02-serviceconnection-unaffected-javap.txt` | `javap` proof that `JdbcContainerConnectionDetailsFactory` is typed against `org.testcontainers.containers.JdbcDatabaseContainer<?>` — unmoved by the 2.0 package split, which is why `@ServiceConnection` needed no changes |
|
| `docs/output/02-serviceconnection-unaffected-javap.txt` | `javap` proof that `JdbcContainerConnectionDetailsFactory` is typed against `org.testcontainers.containers.JdbcDatabaseContainer<?>` — unmoved by the 2.0 package split, which is why `@ServiceConnection` needed no changes |
|
||||||
| `docs/output/04-service-connection-without-guard-fails.txt` | The real `ContainerFetchException` / `IllegalStateException` from trying to start a Postgres container with no Docker daemon present, and no guard against that |
|
| `docs/output/04-service-connection-without-guard-fails.txt` | The real `ContainerFetchException` / `IllegalStateException` from trying to start a Postgres container with no Docker daemon present, and no guard against that |
|
||||||
| `docs/output/05-service-connection-skips-cleanly.txt` | The same absence of Docker, this time behind `@EnabledIfDockerAvailable` — one line, `Skipped: 1`, no failure |
|
| `docs/output/05-service-connection-skips-cleanly.txt` | The same absence of Docker, this time behind `@EnabledIfDockerAvailable` — one line, `Skipped: 1`, no failure |
|
||||||
|
| `docs/output/06-autoconfigurejdbc-meta-annotation-javap.txt` | `javap` proof that `AutoConfigureJdbc.class` is meta-annotated with `@AutoConfigureDataSourceInitialization`, plus the matching `META-INF/spring/...AutoConfigureDataSourceInitialization.imports` file contents from both `spring-boot-jdbc-test` and `spring-boot-flyway` — the actual mechanism behind `FlywayRunsByDefaultTest` |
|
||||||
|
|
||||||
## What's sourced from code, not run here
|
## What's sourced from code, not run here
|
||||||
|
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ WARNING: sun.misc.Unsafe::staticFieldBase will be removed in a future release
|
|||||||
[INFO] -------------------------------------------------------
|
[INFO] -------------------------------------------------------
|
||||||
Picked up JAVA_TOOL_OPTIONS: -Djavax.net.ssl.trustStore=/etc/ssl/certs/java/cacerts -Djavax.net.ssl.trustStoreType=JKS -Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=34689 -Dhttp.nonProxyHosts=localhost|127.0.0.1|::1|127.*|0.*|::|169.254.*|api.anthropic.com|api-staging.anthropic.com|api-pr-preview.anthropic.com|mcp-proxy.anthropic.com|mcp-proxy-staging.anthropic.com|registry.npmjs.org|jsr.io|npm.jsr.io|pypi.org|files.pythonhosted.org|index.crates.io|proxy.golang.org|host.docker.internal|10.*|172.16.*|172.17.*|172.18.*|172.19.*|172.20.*|172.21.*|172.22.*|172.23.*|172.24.*|172.25.*|172.26.*|172.27.*|172.28.*|172.29.*|172.30.*|172.31.*|192.168.*|100.64.0.0/10|*.svc.cluster.local|*.svc.cluster.local -Djdk.http.auth.tunneling.disabledSchemes= -Djdk.http.auth.proxying.disabledSchemes=
|
Picked up JAVA_TOOL_OPTIONS: -Djavax.net.ssl.trustStore=/etc/ssl/certs/java/cacerts -Djavax.net.ssl.trustStoreType=JKS -Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=34689 -Dhttp.nonProxyHosts=localhost|127.0.0.1|::1|127.*|0.*|::|169.254.*|api.anthropic.com|api-staging.anthropic.com|api-pr-preview.anthropic.com|mcp-proxy.anthropic.com|mcp-proxy-staging.anthropic.com|registry.npmjs.org|jsr.io|npm.jsr.io|pypi.org|files.pythonhosted.org|index.crates.io|proxy.golang.org|host.docker.internal|10.*|172.16.*|172.17.*|172.18.*|172.19.*|172.20.*|172.21.*|172.22.*|172.23.*|172.24.*|172.25.*|172.26.*|172.27.*|172.28.*|172.29.*|172.30.*|172.31.*|192.168.*|100.64.0.0/10|*.svc.cluster.local|*.svc.cluster.local -Djdk.http.auth.tunneling.disabledSchemes= -Djdk.http.auth.proxying.disabledSchemes=
|
||||||
[INFO] Running com.ankurm.datajpa.DefaultReplacementTest
|
[INFO] Running com.ankurm.datajpa.DefaultReplacementTest
|
||||||
17:19:49.092 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils -- Could not detect default configuration classes for test class [com.ankurm.datajpa.DefaultReplacementTest]: DefaultReplacementTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
17:55:42.824 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils -- Could not detect default configuration classes for test class [com.ankurm.datajpa.DefaultReplacementTest]: DefaultReplacementTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
||||||
17:19:49.365 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper -- Found @SpringBootConfiguration com.ankurm.datajpa.DataJpaTestcontainersApplication for test class com.ankurm.datajpa.DefaultReplacementTest
|
17:55:43.042 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper -- Found @SpringBootConfiguration com.ankurm.datajpa.DataJpaTestcontainersApplication for test class com.ankurm.datajpa.DefaultReplacementTest
|
||||||
17:19:49.370 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils -- Could not detect default configuration classes for test class [com.ankurm.datajpa.DefaultReplacementTest]: DefaultReplacementTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
17:55:43.046 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils -- Could not detect default configuration classes for test class [com.ankurm.datajpa.DefaultReplacementTest]: DefaultReplacementTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
||||||
17:19:49.405 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper -- Found @SpringBootConfiguration com.ankurm.datajpa.DataJpaTestcontainersApplication for test class com.ankurm.datajpa.DefaultReplacementTest
|
17:55:43.073 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper -- Found @SpringBootConfiguration com.ankurm.datajpa.DataJpaTestcontainersApplication for test class com.ankurm.datajpa.DefaultReplacementTest
|
||||||
|
|
||||||
. ____ _ __ _ _
|
. ____ _ __ _ _
|
||||||
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
|
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
|
||||||
@@ -50,39 +50,39 @@ Picked up JAVA_TOOL_OPTIONS: -Djavax.net.ssl.trustStore=/etc/ssl/certs/java/cace
|
|||||||
|
|
||||||
:: Spring Boot :: (v4.1.1)
|
:: Spring Boot :: (v4.1.1)
|
||||||
|
|
||||||
2026-10-08T17:19:50.032+05:30 INFO 2231 --- [ main] c.ankurm.datajpa.DefaultReplacementTest : Starting DefaultReplacementTest using Java 25.0.4.1 with PID 2231 (started by root in /home/claude/spring-boot-demo/data-jpa-testcontainers)
|
2026-10-08T17:55:43.593+05:30 INFO 10940 --- [ main] c.ankurm.datajpa.DefaultReplacementTest : Starting DefaultReplacementTest using Java 25.0.4.1 with PID 10940 (started by root in /home/claude/spring-boot-demo/data-jpa-testcontainers)
|
||||||
2026-10-08T17:19:50.034+05:30 INFO 2231 --- [ main] c.ankurm.datajpa.DefaultReplacementTest : No active profile set, falling back to 1 default profile: "default"
|
2026-10-08T17:55:43.595+05:30 INFO 10940 --- [ main] c.ankurm.datajpa.DefaultReplacementTest : No active profile set, falling back to 1 default profile: "default"
|
||||||
2026-10-08T17:19:50.614+05:30 INFO 2231 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
|
2026-10-08T17:55:44.217+05:30 INFO 10940 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
|
||||||
2026-10-08T17:19:50.751+05:30 INFO 2231 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 126 ms. Found 1 JPA repository interface.
|
2026-10-08T17:55:44.349+05:30 INFO 10940 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 118 ms. Found 1 JPA repository interface.
|
||||||
2026-10-08T17:19:50.849+05:30 INFO 2231 --- [ main] beddedDataSourceBeanFactoryPostProcessor : Replacing 'dataSource' DataSource bean with embedded version
|
2026-10-08T17:55:44.495+05:30 INFO 10940 --- [ main] beddedDataSourceBeanFactoryPostProcessor : Replacing 'dataSource' DataSource bean with embedded version
|
||||||
2026-10-08T17:19:51.122+05:30 INFO 2231 --- [ main] o.s.j.d.e.EmbeddedDatabaseFactory : Starting embedded database: url='jdbc:h2:mem:27737b58-793d-4017-ae78-1a78ebfc5b27;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
|
2026-10-08T17:55:44.784+05:30 INFO 10940 --- [ main] o.s.j.d.e.EmbeddedDatabaseFactory : Starting embedded database: url='jdbc:h2:mem:4440be02-551f-486e-a4b1-2182bb84c7a5;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
|
||||||
2026-10-08T17:19:51.815+05:30 INFO 2231 --- [ main] org.flywaydb.core.FlywayExecutor : Database: jdbc:h2:mem:27737b58-793d-4017-ae78-1a78ebfc5b27 (H2 2.4)
|
2026-10-08T17:55:45.448+05:30 INFO 10940 --- [ main] org.flywaydb.core.FlywayExecutor : Database: jdbc:h2:mem:4440be02-551f-486e-a4b1-2182bb84c7a5 (H2 2.4)
|
||||||
2026-10-08T17:19:51.888+05:30 WARN 2231 --- [ main] o.f.c.internal.database.base.Database : Using H2 2.4.240 which is newer than the version Flyway has been verified with. The latest verified version of H2 is 2.3.232.
|
2026-10-08T17:55:45.514+05:30 WARN 10940 --- [ main] o.f.c.internal.database.base.Database : Using H2 2.4.240 which is newer than the version Flyway has been verified with. The latest verified version of H2 is 2.3.232.
|
||||||
2026-10-08T17:19:51.949+05:30 INFO 2231 --- [ main] o.f.c.i.s.JdbcTableSchemaHistory : Schema history table "PUBLIC"."flyway_schema_history" does not exist yet
|
2026-10-08T17:55:45.551+05:30 INFO 10940 --- [ main] o.f.c.i.s.JdbcTableSchemaHistory : Schema history table "PUBLIC"."flyway_schema_history" does not exist yet
|
||||||
2026-10-08T17:19:51.952+05:30 INFO 2231 --- [ main] o.f.core.internal.command.DbValidate : Successfully validated 1 migration (execution time 00:00.040s)
|
2026-10-08T17:55:45.555+05:30 INFO 10940 --- [ main] o.f.core.internal.command.DbValidate : Successfully validated 1 migration (execution time 00:00.014s)
|
||||||
2026-10-08T17:19:51.960+05:30 INFO 2231 --- [ main] o.f.c.i.s.JdbcTableSchemaHistory : Creating Schema History table "PUBLIC"."flyway_schema_history" ...
|
2026-10-08T17:55:45.582+05:30 INFO 10940 --- [ main] o.f.c.i.s.JdbcTableSchemaHistory : Creating Schema History table "PUBLIC"."flyway_schema_history" ...
|
||||||
2026-10-08T17:19:52.002+05:30 INFO 2231 --- [ main] o.f.core.internal.command.DbMigrate : Current version of schema "PUBLIC": << Empty Schema >>
|
2026-10-08T17:55:45.640+05:30 INFO 10940 --- [ main] o.f.core.internal.command.DbMigrate : Current version of schema "PUBLIC": << Empty Schema >>
|
||||||
2026-10-08T17:19:52.015+05:30 INFO 2231 --- [ main] o.f.core.internal.command.DbMigrate : Migrating schema "PUBLIC" to version "1 - create product"
|
2026-10-08T17:55:45.652+05:30 INFO 10940 --- [ main] o.f.core.internal.command.DbMigrate : Migrating schema "PUBLIC" to version "1 - create product"
|
||||||
2026-10-08T17:19:52.034+05:30 INFO 2231 --- [ main] o.f.core.internal.command.DbMigrate : Successfully applied 1 migration to schema "PUBLIC", now at version v1 (execution time 00:00.008s)
|
2026-10-08T17:55:45.750+05:30 INFO 10940 --- [ main] o.f.core.internal.command.DbMigrate : Successfully applied 1 migration to schema "PUBLIC", now at version v1 (execution time 00:00.016s)
|
||||||
2026-10-08T17:19:52.268+05:30 INFO 2231 --- [ main] org.hibernate.orm.jpa : HHH008540: Processing PersistenceUnitInfo [name: default]
|
2026-10-08T17:55:46.001+05:30 INFO 10940 --- [ main] org.hibernate.orm.jpa : HHH008540: Processing PersistenceUnitInfo [name: default]
|
||||||
2026-10-08T17:19:52.332+05:30 INFO 2231 --- [ main] org.hibernate.orm.core : HHH000001: Hibernate ORM core version 7.4.5.Final
|
2026-10-08T17:55:46.079+05:30 INFO 10940 --- [ main] org.hibernate.orm.core : HHH000001: Hibernate ORM core version 7.4.5.Final
|
||||||
2026-10-08T17:19:52.886+05:30 INFO 2231 --- [ main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer
|
2026-10-08T17:55:46.707+05:30 INFO 10940 --- [ main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer
|
||||||
2026-10-08T17:19:53.006+05:30 INFO 2231 --- [ main] org.hibernate.orm.connections.pooling : HHH10001005: Database info:
|
2026-10-08T17:55:46.832+05:30 INFO 10940 --- [ main] org.hibernate.orm.connections.pooling : HHH10001005: Database info:
|
||||||
Database JDBC URL [jdbc:h2:mem:27737b58-793d-4017-ae78-1a78ebfc5b27]
|
Database JDBC URL [jdbc:h2:mem:4440be02-551f-486e-a4b1-2182bb84c7a5]
|
||||||
Database driver: H2 JDBC Driver
|
Database driver: H2 JDBC Driver
|
||||||
Database dialect: H2Dialect
|
Database dialect: H2Dialect
|
||||||
Database version: 2.4.240
|
Database version: 2.4.240
|
||||||
Default catalog/schema: 27737B58-793D-4017-AE78-1A78EBFC5B27/PUBLIC
|
Default catalog/schema: 4440BE02-551F-486E-A4B1-2182BB84C7A5/PUBLIC
|
||||||
Autocommit mode: undefined/unknown
|
Autocommit mode: undefined/unknown
|
||||||
Isolation level: READ_COMMITTED [default READ_COMMITTED]
|
Isolation level: READ_COMMITTED [default READ_COMMITTED]
|
||||||
JDBC fetch size: 100
|
JDBC fetch size: 100
|
||||||
Pool: DataSourceConnectionProvider
|
Pool: DataSourceConnectionProvider
|
||||||
Minimum pool size: undefined/unknown
|
Minimum pool size: undefined/unknown
|
||||||
Maximum pool size: undefined/unknown
|
Maximum pool size: undefined/unknown
|
||||||
2026-10-08T17:19:54.129+05:30 INFO 2231 --- [ main] org.hibernate.orm.core : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
|
2026-10-08T17:55:47.973+05:30 INFO 10940 --- [ main] org.hibernate.orm.core : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
|
||||||
2026-10-08T17:19:54.145+05:30 INFO 2231 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
|
2026-10-08T17:55:47.989+05:30 INFO 10940 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
|
||||||
2026-10-08T17:19:54.332+05:30 INFO 2231 --- [ main] o.s.d.j.r.query.QueryEnhancerFactories : Hibernate is in classpath; If applicable, HQL parser will be used.
|
2026-10-08T17:55:48.156+05:30 INFO 10940 --- [ main] o.s.d.j.r.query.QueryEnhancerFactories : Hibernate is in classpath; If applicable, HQL parser will be used.
|
||||||
2026-10-08T17:19:54.604+05:30 INFO 2231 --- [ main] c.ankurm.datajpa.DefaultReplacementTest : Started DefaultReplacementTest in 5.076 seconds (process running for 7.153)
|
2026-10-08T17:55:48.476+05:30 INFO 10940 --- [ main] c.ankurm.datajpa.DefaultReplacementTest : Started DefaultReplacementTest in 5.325 seconds (process running for 7.158)
|
||||||
Mockito is currently self-attaching to enable the inline-mock-maker. This will no longer work in future releases of the JDK. Please add Mockito as an agent to your build as described in Mockito's documentation: https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#0.3
|
Mockito is currently self-attaching to enable the inline-mock-maker. This will no longer work in future releases of the JDK. Please add Mockito as an agent to your build as described in Mockito's documentation: https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#0.3
|
||||||
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
|
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
|
||||||
WARNING: A Java agent has been loaded dynamically (/root/.m2/repository/net/bytebuddy/byte-buddy-agent/1.18.11/byte-buddy-agent-1.18.11.jar)
|
WARNING: A Java agent has been loaded dynamically (/root/.m2/repository/net/bytebuddy/byte-buddy-agent/1.18.11/byte-buddy-agent-1.18.11.jar)
|
||||||
@@ -95,12 +95,12 @@ JDBC reports database product name: H2
|
|||||||
Hibernate: insert into product (name,sku,id) values (?,?,default)
|
Hibernate: insert into product (name,sku,id) values (?,?,default)
|
||||||
Hibernate: select p1_0.id,p1_0.name,p1_0.sku from product p1_0 where p1_0.sku=?
|
Hibernate: select p1_0.id,p1_0.name,p1_0.sku from product p1_0 where p1_0.sku=?
|
||||||
Hibernate: select count(*) from product p1_0
|
Hibernate: select count(*) from product p1_0
|
||||||
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 7.329 s -- in com.ankurm.datajpa.DefaultReplacementTest
|
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 7.500 s -- in com.ankurm.datajpa.DefaultReplacementTest
|
||||||
[INFO] Running com.ankurm.datajpa.NoSubstitutionStillSilentlyUsesH2Test
|
[INFO] Running com.ankurm.datajpa.NoSubstitutionStillSilentlyUsesH2Test
|
||||||
2026-10-08T17:19:56.108+05:30 INFO 2231 --- [ main] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.ankurm.datajpa.NoSubstitutionStillSilentlyUsesH2Test]: NoSubstitutionStillSilentlyUsesH2Test does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
2026-10-08T17:55:50.002+05:30 INFO 10940 --- [ main] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.ankurm.datajpa.NoSubstitutionStillSilentlyUsesH2Test]: NoSubstitutionStillSilentlyUsesH2Test does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
||||||
2026-10-08T17:19:56.189+05:30 INFO 2231 --- [ main] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.ankurm.datajpa.DataJpaTestcontainersApplication for test class com.ankurm.datajpa.NoSubstitutionStillSilentlyUsesH2Test
|
2026-10-08T17:55:50.040+05:30 INFO 10940 --- [ main] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.ankurm.datajpa.DataJpaTestcontainersApplication for test class com.ankurm.datajpa.NoSubstitutionStillSilentlyUsesH2Test
|
||||||
2026-10-08T17:19:56.197+05:30 INFO 2231 --- [ main] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.ankurm.datajpa.NoSubstitutionStillSilentlyUsesH2Test]: NoSubstitutionStillSilentlyUsesH2Test does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
2026-10-08T17:55:50.041+05:30 INFO 10940 --- [ main] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.ankurm.datajpa.NoSubstitutionStillSilentlyUsesH2Test]: NoSubstitutionStillSilentlyUsesH2Test does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
||||||
2026-10-08T17:19:56.238+05:30 INFO 2231 --- [ main] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.ankurm.datajpa.DataJpaTestcontainersApplication for test class com.ankurm.datajpa.NoSubstitutionStillSilentlyUsesH2Test
|
2026-10-08T17:55:50.069+05:30 INFO 10940 --- [ main] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.ankurm.datajpa.DataJpaTestcontainersApplication for test class com.ankurm.datajpa.NoSubstitutionStillSilentlyUsesH2Test
|
||||||
|
|
||||||
. ____ _ __ _ _
|
. ____ _ __ _ _
|
||||||
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
|
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
|
||||||
@@ -111,74 +111,75 @@ Hibernate: select count(*) from product p1_0
|
|||||||
|
|
||||||
:: Spring Boot :: (v4.1.1)
|
:: Spring Boot :: (v4.1.1)
|
||||||
|
|
||||||
2026-10-08T17:19:56.294+05:30 INFO 2231 --- [ main] .d.NoSubstitutionStillSilentlyUsesH2Test : Starting NoSubstitutionStillSilentlyUsesH2Test using Java 25.0.4.1 with PID 2231 (started by root in /home/claude/spring-boot-demo/data-jpa-testcontainers)
|
2026-10-08T17:55:50.166+05:30 INFO 10940 --- [ main] .d.NoSubstitutionStillSilentlyUsesH2Test : Starting NoSubstitutionStillSilentlyUsesH2Test using Java 25.0.4.1 with PID 10940 (started by root in /home/claude/spring-boot-demo/data-jpa-testcontainers)
|
||||||
2026-10-08T17:19:56.295+05:30 INFO 2231 --- [ main] .d.NoSubstitutionStillSilentlyUsesH2Test : No active profile set, falling back to 1 default profile: "default"
|
2026-10-08T17:55:50.167+05:30 INFO 10940 --- [ main] .d.NoSubstitutionStillSilentlyUsesH2Test : No active profile set, falling back to 1 default profile: "default"
|
||||||
2026-10-08T17:19:56.452+05:30 INFO 2231 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
|
2026-10-08T17:55:50.366+05:30 INFO 10940 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
|
||||||
2026-10-08T17:19:56.469+05:30 INFO 2231 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 13 ms. Found 1 JPA repository interface.
|
2026-10-08T17:55:50.381+05:30 INFO 10940 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 12 ms. Found 1 JPA repository interface.
|
||||||
2026-10-08T17:19:56.642+05:30 INFO 2231 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
|
2026-10-08T17:55:50.538+05:30 INFO 10940 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
|
||||||
2026-10-08T17:19:56.665+05:30 INFO 2231 --- [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn9: url=jdbc:h2:mem:fb5a3fcb-6cc0-4a37-baff-7dbd0bfb51fd user=SA
|
2026-10-08T17:55:50.563+05:30 INFO 10940 --- [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn9: url=jdbc:h2:mem:59a60d3a-9329-4255-85ca-9683b850ef31 user=SA
|
||||||
2026-10-08T17:19:56.667+05:30 INFO 2231 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
|
2026-10-08T17:55:50.566+05:30 INFO 10940 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
|
||||||
2026-10-08T17:19:56.673+05:30 INFO 2231 --- [ main] org.flywaydb.core.FlywayExecutor : Database: jdbc:h2:mem:fb5a3fcb-6cc0-4a37-baff-7dbd0bfb51fd (H2 2.4)
|
2026-10-08T17:55:50.573+05:30 INFO 10940 --- [ main] org.flywaydb.core.FlywayExecutor : Database: jdbc:h2:mem:59a60d3a-9329-4255-85ca-9683b850ef31 (H2 2.4)
|
||||||
2026-10-08T17:19:56.686+05:30 WARN 2231 --- [ main] o.f.c.internal.database.base.Database : Using H2 2.4.240 which is newer than the version Flyway has been verified with. The latest verified version of H2 is 2.3.232.
|
2026-10-08T17:55:50.597+05:30 WARN 10940 --- [ main] o.f.c.internal.database.base.Database : Using H2 2.4.240 which is newer than the version Flyway has been verified with. The latest verified version of H2 is 2.3.232.
|
||||||
2026-10-08T17:19:56.690+05:30 INFO 2231 --- [ main] o.f.c.i.s.JdbcTableSchemaHistory : Schema history table "PUBLIC"."flyway_schema_history" does not exist yet
|
2026-10-08T17:55:50.607+05:30 INFO 10940 --- [ main] o.f.c.i.s.JdbcTableSchemaHistory : Schema history table "PUBLIC"."flyway_schema_history" does not exist yet
|
||||||
2026-10-08T17:19:56.691+05:30 INFO 2231 --- [ main] o.f.core.internal.command.DbValidate : Successfully validated 1 migration (execution time 00:00.002s)
|
2026-10-08T17:55:50.608+05:30 INFO 10940 --- [ main] o.f.core.internal.command.DbValidate : Successfully validated 1 migration (execution time 00:00.005s)
|
||||||
2026-10-08T17:19:56.693+05:30 INFO 2231 --- [ main] o.f.c.i.s.JdbcTableSchemaHistory : Creating Schema History table "PUBLIC"."flyway_schema_history" ...
|
2026-10-08T17:55:50.610+05:30 INFO 10940 --- [ main] o.f.c.i.s.JdbcTableSchemaHistory : Creating Schema History table "PUBLIC"."flyway_schema_history" ...
|
||||||
2026-10-08T17:19:56.703+05:30 INFO 2231 --- [ main] o.f.core.internal.command.DbMigrate : Current version of schema "PUBLIC": << Empty Schema >>
|
2026-10-08T17:55:50.723+05:30 INFO 10940 --- [ main] o.f.core.internal.command.DbMigrate : Current version of schema "PUBLIC": << Empty Schema >>
|
||||||
2026-10-08T17:19:56.707+05:30 INFO 2231 --- [ main] o.f.core.internal.command.DbMigrate : Migrating schema "PUBLIC" to version "1 - create product"
|
2026-10-08T17:55:50.735+05:30 INFO 10940 --- [ main] o.f.core.internal.command.DbMigrate : Migrating schema "PUBLIC" to version "1 - create product"
|
||||||
2026-10-08T17:19:56.715+05:30 INFO 2231 --- [ main] o.f.core.internal.command.DbMigrate : Successfully applied 1 migration to schema "PUBLIC", now at version v1 (execution time 00:00.004s)
|
2026-10-08T17:55:50.745+05:30 INFO 10940 --- [ main] o.f.core.internal.command.DbMigrate : Successfully applied 1 migration to schema "PUBLIC", now at version v1 (execution time 00:00.006s)
|
||||||
2026-10-08T17:19:56.752+05:30 INFO 2231 --- [ main] org.hibernate.orm.jpa : HHH008540: Processing PersistenceUnitInfo [name: default]
|
2026-10-08T17:55:50.829+05:30 INFO 10940 --- [ main] org.hibernate.orm.jpa : HHH008540: Processing PersistenceUnitInfo [name: default]
|
||||||
2026-10-08T17:19:56.808+05:30 INFO 2231 --- [ main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer
|
2026-10-08T17:55:50.897+05:30 INFO 10940 --- [ main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer
|
||||||
2026-10-08T17:19:56.814+05:30 INFO 2231 --- [ main] org.hibernate.orm.connections.pooling : HHH10001005: Database info:
|
2026-10-08T17:55:50.902+05:30 INFO 10940 --- [ main] org.hibernate.orm.connections.pooling : HHH10001005: Database info:
|
||||||
Database JDBC URL [jdbc:h2:mem:fb5a3fcb-6cc0-4a37-baff-7dbd0bfb51fd]
|
Database JDBC URL [jdbc:h2:mem:59a60d3a-9329-4255-85ca-9683b850ef31]
|
||||||
Database driver: H2 JDBC Driver
|
Database driver: H2 JDBC Driver
|
||||||
Database dialect: H2Dialect
|
Database dialect: H2Dialect
|
||||||
Database version: 2.4.240
|
Database version: 2.4.240
|
||||||
Default catalog/schema: FB5A3FCB-6CC0-4A37-BAFF-7DBD0BFB51FD/PUBLIC
|
Default catalog/schema: 59A60D3A-9329-4255-85CA-9683B850EF31/PUBLIC
|
||||||
Autocommit mode: undefined/unknown
|
Autocommit mode: undefined/unknown
|
||||||
Isolation level: READ_COMMITTED [default READ_COMMITTED]
|
Isolation level: READ_COMMITTED [default READ_COMMITTED]
|
||||||
JDBC fetch size: 100
|
JDBC fetch size: 100
|
||||||
Pool: DataSourceConnectionProvider
|
Pool: DataSourceConnectionProvider
|
||||||
Minimum pool size: undefined/unknown
|
Minimum pool size: undefined/unknown
|
||||||
Maximum pool size: undefined/unknown
|
Maximum pool size: undefined/unknown
|
||||||
2026-10-08T17:19:56.850+05:30 INFO 2231 --- [ main] org.hibernate.orm.core : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
|
2026-10-08T17:55:50.956+05:30 INFO 10940 --- [ main] org.hibernate.orm.core : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
|
||||||
2026-10-08T17:19:56.851+05:30 INFO 2231 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
|
2026-10-08T17:55:50.958+05:30 INFO 10940 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
|
||||||
2026-10-08T17:19:56.915+05:30 INFO 2231 --- [ main] .d.NoSubstitutionStillSilentlyUsesH2Test : Started NoSubstitutionStillSilentlyUsesH2Test in 0.668 seconds (process running for 9.464)
|
2026-10-08T17:55:51.035+05:30 INFO 10940 --- [ main] .d.NoSubstitutionStillSilentlyUsesH2Test : Started NoSubstitutionStillSilentlyUsesH2Test in 0.949 seconds (process running for 9.717)
|
||||||
JDBC reports database product name: H2 (even with replace = Replace.NONE and no @ServiceConnection anywhere)
|
JDBC reports database product name: H2 (even with replace = Replace.NONE and no @ServiceConnection anywhere)
|
||||||
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.852 s -- in com.ankurm.datajpa.NoSubstitutionStillSilentlyUsesH2Test
|
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.083 s -- in com.ankurm.datajpa.NoSubstitutionStillSilentlyUsesH2Test
|
||||||
[INFO] Running com.ankurm.datajpa.FlywayDoesNotRunUnderPlainDataJpaTestTest
|
[INFO] Running com.ankurm.datajpa.ExplicitFlywayImportIsRedundantTest
|
||||||
2026-10-08T17:19:56.952+05:30 INFO 2231 --- [ main] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.ankurm.datajpa.FlywayDoesNotRunUnderPlainDataJpaTestTest]: FlywayDoesNotRunUnderPlainDataJpaTestTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
2026-10-08T17:55:51.081+05:30 INFO 10940 --- [ main] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.ankurm.datajpa.ExplicitFlywayImportIsRedundantTest]: ExplicitFlywayImportIsRedundantTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
||||||
2026-10-08T17:19:57.008+05:30 INFO 2231 --- [ main] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.ankurm.datajpa.DataJpaTestcontainersApplication for test class com.ankurm.datajpa.FlywayDoesNotRunUnderPlainDataJpaTestTest
|
2026-10-08T17:55:51.135+05:30 INFO 10940 --- [ main] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.ankurm.datajpa.DataJpaTestcontainersApplication for test class com.ankurm.datajpa.ExplicitFlywayImportIsRedundantTest
|
||||||
2026-10-08T17:19:57.008+05:30 INFO 2231 --- [ main] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.ankurm.datajpa.FlywayDoesNotRunUnderPlainDataJpaTestTest]: FlywayDoesNotRunUnderPlainDataJpaTestTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
2026-10-08T17:55:51.139+05:30 INFO 10940 --- [ main] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.ankurm.datajpa.ExplicitFlywayImportIsRedundantTest]: ExplicitFlywayImportIsRedundantTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
||||||
2026-10-08T17:19:57.064+05:30 INFO 2231 --- [ main] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.ankurm.datajpa.DataJpaTestcontainersApplication for test class com.ankurm.datajpa.FlywayDoesNotRunUnderPlainDataJpaTestTest
|
2026-10-08T17:55:51.195+05:30 INFO 10940 --- [ main] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.ankurm.datajpa.DataJpaTestcontainersApplication for test class com.ankurm.datajpa.ExplicitFlywayImportIsRedundantTest
|
||||||
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.137 s -- in com.ankurm.datajpa.FlywayDoesNotRunUnderPlainDataJpaTestTest
|
flyway_schema_history real migration rows (rank >= 0): 1
|
||||||
[INFO] Running com.ankurm.datajpa.FlywayRunsWhenExplicitlyImportedTest
|
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.226 s -- in com.ankurm.datajpa.ExplicitFlywayImportIsRedundantTest
|
||||||
2026-10-08T17:19:57.091+05:30 INFO 2231 --- [ main] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.ankurm.datajpa.FlywayRunsWhenExplicitlyImportedTest]: FlywayRunsWhenExplicitlyImportedTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
2026-10-08T17:55:51.324+05:30 INFO 10940 --- [ main] org.testcontainers.DockerClientFactory : Testcontainers version: 2.0.5
|
||||||
2026-10-08T17:19:57.107+05:30 INFO 2231 --- [ main] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.ankurm.datajpa.DataJpaTestcontainersApplication for test class com.ankurm.datajpa.FlywayRunsWhenExplicitlyImportedTest
|
|
||||||
2026-10-08T17:19:57.107+05:30 INFO 2231 --- [ main] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.ankurm.datajpa.FlywayRunsWhenExplicitlyImportedTest]: FlywayRunsWhenExplicitlyImportedTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
|
||||||
2026-10-08T17:19:57.132+05:30 INFO 2231 --- [ main] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.ankurm.datajpa.DataJpaTestcontainersApplication for test class com.ankurm.datajpa.FlywayRunsWhenExplicitlyImportedTest
|
|
||||||
flyway_schema_history row: version=1 description=create product success=true
|
|
||||||
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.085 s -- in com.ankurm.datajpa.FlywayRunsWhenExplicitlyImportedTest
|
|
||||||
2026-10-08T17:19:57.218+05:30 INFO 2231 --- [ main] org.testcontainers.DockerClientFactory : Testcontainers version: 2.0.5
|
|
||||||
WARNING: A restricted method in java.lang.System has been called
|
WARNING: A restricted method in java.lang.System has been called
|
||||||
WARNING: java.lang.System::load has been called by com.sun.jna.Native in an unnamed module (file:/root/.m2/repository/net/java/dev/jna/jna/5.18.1/jna-5.18.1.jar)
|
WARNING: java.lang.System::load has been called by com.sun.jna.Native in an unnamed module (file:/root/.m2/repository/net/java/dev/jna/jna/5.18.1/jna-5.18.1.jar)
|
||||||
WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module
|
WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module
|
||||||
WARNING: Restricted methods will be blocked in a future release unless native access is enabled
|
WARNING: Restricted methods will be blocked in a future release unless native access is enabled
|
||||||
|
|
||||||
2026-10-08T17:19:57.537+05:30 INFO 2231 --- [ main] .t.d.DockerMachineClientProviderStrategy : docker-machine executable was not found on PATH ([/opt/jdk-25/bin, /home/claude/.npm-global/bin, /nix/var/nix/profiles/default/bin, /root/.local/bin, /root/.cargo/bin, /usr/local/go/bin, /opt/node22/bin, /opt/maven/bin, /opt/gradle/bin, /opt/rbenv/bin, /root/.bun/bin, /usr/local/sbin, /usr/local/bin, /usr/sbin, /usr/bin, /sbin, /bin])
|
2026-10-08T17:55:51.689+05:30 INFO 10940 --- [ main] .t.d.DockerMachineClientProviderStrategy : docker-machine executable was not found on PATH ([/opt/jdk-25/bin, /home/claude/.npm-global/bin, /nix/var/nix/profiles/default/bin, /root/.local/bin, /root/.cargo/bin, /usr/local/go/bin, /opt/node22/bin, /opt/maven/bin, /opt/gradle/bin, /opt/rbenv/bin, /root/.bun/bin, /usr/local/sbin, /usr/local/bin, /usr/sbin, /usr/bin, /sbin, /bin])
|
||||||
2026-10-08T17:19:57.538+05:30 ERROR 2231 --- [ main] o.t.d.DockerClientProviderStrategy : Could not find a valid Docker environment. Please check configuration. Attempted configurations were:
|
2026-10-08T17:55:51.691+05:30 ERROR 10940 --- [ main] o.t.d.DockerClientProviderStrategy : Could not find a valid Docker environment. Please check configuration. Attempted configurations were:
|
||||||
UnixSocketClientProviderStrategy: failed with exception InvalidConfigurationException (Could not find unix domain socket). Root cause NoSuchFileException (/var/run/docker.sock)
|
UnixSocketClientProviderStrategy: failed with exception InvalidConfigurationException (Could not find unix domain socket). Root cause NoSuchFileException (/var/run/docker.sock)
|
||||||
DockerDesktopClientProviderStrategy: failed with exception NullPointerException (Cannot invoke "java.nio.file.Path.toString()" because the return value of "org.testcontainers.dockerclient.DockerDesktopClientProviderStrategy.getSocketPath()" is null)As no valid configuration was found, execution cannot continue.
|
DockerDesktopClientProviderStrategy: failed with exception NullPointerException (Cannot invoke "java.nio.file.Path.toString()" because the return value of "org.testcontainers.dockerclient.DockerDesktopClientProviderStrategy.getSocketPath()" is null)As no valid configuration was found, execution cannot continue.
|
||||||
See https://java.testcontainers.org/on_failure.html for more details.
|
See https://java.testcontainers.org/on_failure.html for more details.
|
||||||
[INFO] Running com.ankurm.datajpa.ServiceConnectionSkipsCleanlyTest
|
[INFO] Running com.ankurm.datajpa.ServiceConnectionSkipsCleanlyTest
|
||||||
[WARNING] Tests run: 1, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 0.001 s -- in com.ankurm.datajpa.ServiceConnectionSkipsCleanlyTest
|
[WARNING] Tests run: 1, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 0.009 s -- in com.ankurm.datajpa.ServiceConnectionSkipsCleanlyTest
|
||||||
|
[INFO] Running com.ankurm.datajpa.FlywayRunsByDefaultTest
|
||||||
|
2026-10-08T17:55:51.702+05:30 INFO 10940 --- [ main] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.ankurm.datajpa.FlywayRunsByDefaultTest]: FlywayRunsByDefaultTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
||||||
|
2026-10-08T17:55:51.716+05:30 INFO 10940 --- [ main] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.ankurm.datajpa.DataJpaTestcontainersApplication for test class com.ankurm.datajpa.FlywayRunsByDefaultTest
|
||||||
|
2026-10-08T17:55:51.717+05:30 INFO 10940 --- [ main] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.ankurm.datajpa.FlywayRunsByDefaultTest]: FlywayRunsByDefaultTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
|
||||||
|
2026-10-08T17:55:51.731+05:30 INFO 10940 --- [ main] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.ankurm.datajpa.DataJpaTestcontainersApplication for test class com.ankurm.datajpa.FlywayRunsByDefaultTest
|
||||||
|
flyway_schema_history row: version=1 description=create product success=true
|
||||||
|
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.079 s -- in com.ankurm.datajpa.FlywayRunsByDefaultTest
|
||||||
[INFO]
|
[INFO]
|
||||||
[INFO] Results:
|
[INFO] Results:
|
||||||
[INFO]
|
[INFO]
|
||||||
[INFO] Tests run: 7, Failures: 0, Errors: 0, Skipped: 1
|
[INFO] Tests run: 9, Failures: 0, Errors: 0, Skipped: 1
|
||||||
[INFO]
|
[INFO]
|
||||||
[INFO] ------------------------------------------------------------------------
|
[INFO] ------------------------------------------------------------------------
|
||||||
[INFO] BUILD SUCCESS
|
[INFO] BUILD SUCCESS
|
||||||
[INFO] ------------------------------------------------------------------------
|
[INFO] ------------------------------------------------------------------------
|
||||||
[INFO] Total time: 15.580 s
|
[INFO] Total time: 14.464 s
|
||||||
[INFO] Finished at: 2026-10-08T17:19:57+05:30
|
[INFO] Finished at: 2026-10-08T17:55:51+05:30
|
||||||
[INFO] ------------------------------------------------------------------------
|
[INFO] ------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -75,3 +75,8 @@ $ javap -v org/testcontainers/containers/PostgreSQLContainer.class | grep -i dep
|
|||||||
Deprecated: true
|
Deprecated: true
|
||||||
java.lang.Deprecated
|
java.lang.Deprecated
|
||||||
Deprecated: true
|
Deprecated: true
|
||||||
|
|
||||||
|
$ unzip -l /root/.m2/repository/org/testcontainers/testcontainers-postgresql/2.0.5/testcontainers-postgresql-2.0.5.jar | grep PostgreSQLContainer
|
||||||
|
5533 2026-04-06 22:36 org/testcontainers/postgresql/PostgreSQLContainer.class
|
||||||
|
1745 2026-04-06 22:36 org/testcontainers/containers/PostgreSQLContainerProvider.class
|
||||||
|
6150 2026-04-06 22:36 org/testcontainers/containers/PostgreSQLContainer.class
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
$ javap -v org/springframework/boot/jdbc/test/autoconfigure/AutoConfigureJdbc.class
|
||||||
|
# unzipped from spring-boot-jdbc-test-4.1.1.jar
|
||||||
|
RuntimeVisibleAnnotations:
|
||||||
|
0: #10(#11=[e#12.#13])
|
||||||
|
java.lang.annotation.Target(
|
||||||
|
value=[Ljava/lang/annotation/ElementType;.TYPE]
|
||||||
|
)
|
||||||
|
1: #14(#11=e#15.#16)
|
||||||
|
java.lang.annotation.Retention(
|
||||||
|
value=Ljava/lang/annotation/RetentionPolicy;.RUNTIME
|
||||||
|
)
|
||||||
|
2: #17()
|
||||||
|
java.lang.annotation.Documented
|
||||||
|
3: #18()
|
||||||
|
java.lang.annotation.Inherited
|
||||||
|
4: #19()
|
||||||
|
org.springframework.boot.autoconfigure.ImportAutoConfiguration
|
||||||
|
5: #20()
|
||||||
|
org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureDataSourceInitialization
|
||||||
|
|
||||||
|
$ find . -iname '*DataSourceInitialization*' # inside spring-boot-jdbc-test-4.1.1.jar
|
||||||
|
./META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureDataSourceInitialization.imports
|
||||||
|
|
||||||
|
$ cat META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureDataSourceInitialization.imports
|
||||||
|
org.springframework.boot.jdbc.autoconfigure.DataSourceInitializationAutoConfiguration
|
||||||
|
|
||||||
|
# the SAME resource path, inside spring-boot-flyway-4.1.1.jar instead:
|
||||||
|
$ cat META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureDataSourceInitialization.imports
|
||||||
|
org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration
|
||||||
|
|
||||||
|
$ javap -v org/springframework/boot/flyway/autoconfigure/FlywayAutoConfiguration.class # unzipped from spring-boot-flyway-4.1.1.jar
|
||||||
|
#41 = Utf8 Lorg/springframework/boot/autoconfigure/condition/ConditionalOnClass;
|
||||||
|
#42 = Utf8 value
|
||||||
|
#43 = Utf8 Lorg/flywaydb/core/Flyway;
|
||||||
|
#44 = Utf8 Lorg/springframework/context/annotation/Conditional;
|
||||||
|
--
|
||||||
|
org.springframework.boot.autoconfigure.condition.ConditionalOnClass(
|
||||||
|
value=[class Lorg/flywaydb/core/Flyway;]
|
||||||
|
)
|
||||||
|
2: #44(#42=[c#45])
|
||||||
@@ -47,9 +47,12 @@
|
|||||||
<!-- flyway-core on the classpath is NOT enough to get FlywayAutoConfiguration — that class
|
<!-- flyway-core on the classpath is NOT enough to get FlywayAutoConfiguration — that class
|
||||||
lives in its own starter, a further instance of Boot 4's per-technology module split
|
lives in its own starter, a further instance of Boot 4's per-technology module split
|
||||||
(confirmed by comparing against the db-migrations-flyway-liquibase module, which needs the
|
(confirmed by comparing against the db-migrations-flyway-liquibase module, which needs the
|
||||||
exact same starter). Test scope only: this article's main app never runs Flyway itself, the
|
exact same starter). This is what actually makes Flyway run under @DataJpaTest by default
|
||||||
two test classes that explicitly re-import FlywayAutoConfiguration are what need the class
|
in this module: @AutoConfigureJdbc's @AutoConfigureDataSourceInitialization meta-annotation
|
||||||
on the classpath at all. -->
|
merges a META-INF/spring/...AutoConfigureDataSourceInitialization.imports file from every
|
||||||
|
jar that ships one, and spring-boot-flyway (pulled in by this starter) is one of them —
|
||||||
|
confirmed with javap and unzip, see FlywayRunsByDefaultTest's Javadoc. Test scope only:
|
||||||
|
this article's main app never runs Flyway itself outside the test slice. -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-flyway</artifactId>
|
<artifactId>spring-boot-starter-flyway</artifactId>
|
||||||
|
|||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
package com.ankurm.datajpa;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||||
|
import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest;
|
||||||
|
import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Older advice for this exact situation (including an earlier draft of this module, and more
|
||||||
|
* than one blog post this article will not link to) says to add
|
||||||
|
* {@code @ImportAutoConfiguration(FlywayAutoConfiguration.class)} yourself to get Flyway running
|
||||||
|
* inside a {@code @DataJpaTest}. As {@link FlywayRunsByDefaultTest} now shows, that is no longer
|
||||||
|
* necessary on Spring Boot 4.1 -- the import already happens on its own, by way of
|
||||||
|
* {@code @AutoConfigureJdbc}'s own {@code @AutoConfigureDataSourceInitialization} meta-annotation.
|
||||||
|
*
|
||||||
|
* <p>Adding the explicit import anyway is not harmful. {@code @ImportAutoConfiguration} is
|
||||||
|
* backed by ordinary Spring auto-configuration machinery: the same fully-qualified class name,
|
||||||
|
* however many times it is reached (once through the transitive meta-annotation walk, once
|
||||||
|
* through this class's own explicit annotation), is only ever registered once. This test proves
|
||||||
|
* that directly rather than asserting it from the mechanism alone: exactly one {@code flyway}
|
||||||
|
* bean, and exactly one applied migration -- not two -- with the redundant import sitting right
|
||||||
|
* there on the class.
|
||||||
|
*/
|
||||||
|
@DataJpaTest
|
||||||
|
@ImportAutoConfiguration(FlywayAutoConfiguration.class)
|
||||||
|
class ExplicitFlywayImportIsRedundantTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationContext ctx;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void redundantImportStillProducesExactlyOneFlywayBean() {
|
||||||
|
assertThat(ctx.getBeanNamesForType(org.flywaydb.core.Flyway.class)).hasSize(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void redundantImportDoesNotReapplyTheMigration() throws Exception {
|
||||||
|
try (Connection connection = dataSource.getConnection();
|
||||||
|
Statement statement = connection.createStatement()) {
|
||||||
|
var rs = statement.executeQuery(
|
||||||
|
"select count(*) from \"flyway_schema_history\" where \"installed_rank\" >= 0");
|
||||||
|
assertThat(rs.next()).isTrue();
|
||||||
|
int realMigrationRows = rs.getInt(1);
|
||||||
|
System.out.println("flyway_schema_history real migration rows (rank >= 0): " + realMigrationRows);
|
||||||
|
assertThat(realMigrationRows).isEqualTo(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
-49
@@ -1,49 +0,0 @@
|
|||||||
package com.ankurm.datajpa;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This module has a real Flyway migration, {@code V1__create_product.sql}, and flyway-core is a
|
|
||||||
* main-scope dependency. A plain @DataJpaTest never runs it anyway -- not because of the
|
|
||||||
* embedded-database substitution, but because @DataJpaTest's own curated set of auto-configuration
|
|
||||||
* imports simply does not include FlywayAutoConfiguration or LiquibaseAutoConfiguration at all.
|
|
||||||
* Confirmed by reading the actual import manifests Boot ships inside spring-boot-jdbc-test.jar and
|
|
||||||
* spring-boot-data-jpa-test.jar -- neither file mentions Flyway or Liquibase, in any form, under
|
|
||||||
* any replace setting.
|
|
||||||
*
|
|
||||||
* The {@code product} table exists in this test for a completely different reason: Hibernate's own
|
|
||||||
* {@code ddl-auto}, defaulted on because Boot never detects a schema-management tool in this
|
|
||||||
* slice's context. See {@link FlywayRunsWhenExplicitlyImportedTest} for the one-line fix.
|
|
||||||
*/
|
|
||||||
@DataJpaTest
|
|
||||||
class FlywayDoesNotRunUnderPlainDataJpaTestTest {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private DataSource dataSource;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void productTableExistsButFlywayNeverRan() throws Exception {
|
|
||||||
try (Connection connection = dataSource.getConnection()) {
|
|
||||||
try (ResultSet flywayTable = connection.getMetaData()
|
|
||||||
.getTables(null, null, "FLYWAY_SCHEMA_HISTORY", null)) {
|
|
||||||
assertThat(flywayTable.next())
|
|
||||||
.as("flyway_schema_history should not exist -- Flyway never ran")
|
|
||||||
.isFalse();
|
|
||||||
}
|
|
||||||
try (ResultSet productTable = connection.getMetaData()
|
|
||||||
.getTables(null, null, "PRODUCT", null)) {
|
|
||||||
assertThat(productTable.next())
|
|
||||||
.as("product table should exist anyway -- Hibernate's ddl-auto made it")
|
|
||||||
.isTrue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
package com.ankurm.datajpa;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module has a real Flyway migration, {@code V1__create_product.sql}, and flyway-core
|
||||||
|
* (plus the test-scoped {@code spring-boot-starter-flyway} -- see the module README for why that
|
||||||
|
* second one matters) is on the classpath. A plain {@code @DataJpaTest}, with no extra
|
||||||
|
* annotation anywhere on this class, runs that migration by default.
|
||||||
|
*
|
||||||
|
* <p>An earlier draft of this module asserted the opposite, on the strength of reading
|
||||||
|
* {@code @DataJpaTest}'s four documented meta-annotations ({@code @AutoConfigureDataJpa},
|
||||||
|
* {@code @AutoConfigureJdbc}, {@code @AutoConfigureTestDatabase},
|
||||||
|
* {@code @AutoConfigureTestEntityManager}) and finding that none of their four
|
||||||
|
* {@code .imports} manifests mentions Flyway or Liquibase. That reading is correct and
|
||||||
|
* incomplete: {@code AutoConfigureJdbc.class} is itself meta-annotated with a fifth annotation,
|
||||||
|
* {@code @AutoConfigureDataSourceInitialization} (new in Boot 4.0; confirmed with
|
||||||
|
* {@code javap -v org.springframework.boot.jdbc.test.autoconfigure.AutoConfigureJdbc} against
|
||||||
|
* {@code spring-boot-jdbc-test-4.1.1.jar}), and Spring's own
|
||||||
|
* {@code ImportAutoConfigurationImportSelector} walks the entire meta-annotation tree
|
||||||
|
* transitively -- every annotation, and every meta-annotation on those -- collecting every class
|
||||||
|
* in that tree that is itself annotated with {@code @ImportAutoConfiguration}. That fifth
|
||||||
|
* annotation is one of them.
|
||||||
|
*
|
||||||
|
* <p>{@code @AutoConfigureDataSourceInitialization}'s own {@code .imports} resource is loaded via
|
||||||
|
* {@code ClassLoader.getResources()}, which returns every file at that path across every jar on
|
||||||
|
* the classpath and merges them -- not a single-file lookup. Three jars ship a file at the exact
|
||||||
|
* same resource path
|
||||||
|
* ({@code META-INF/spring/org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureDataSourceInitialization.imports}):
|
||||||
|
* {@code spring-boot-jdbc-test} contributes {@code DataSourceInitializationAutoConfiguration},
|
||||||
|
* {@code spring-boot-flyway} contributes {@code FlywayAutoConfiguration}, and
|
||||||
|
* {@code spring-boot-liquibase} contributes {@code LiquibaseAutoConfiguration}. Confirmed by
|
||||||
|
* unzipping both jars actually on this classpath and reading the file; the Liquibase side was
|
||||||
|
* not independently re-run here (no Liquibase module in this repo) but the same mechanism applies
|
||||||
|
* to it by construction. {@code FlywayAutoConfiguration} is still gated by the ordinary
|
||||||
|
* {@code @ConditionalOnClass(Flyway.class)} -- it only activates once flyway-core is genuinely on
|
||||||
|
* the classpath, which is the one part of the old draft's observation that was never wrong, just
|
||||||
|
* misattributed to the wrong mechanism.
|
||||||
|
*
|
||||||
|
* <p>See {@link ExplicitFlywayImportIsRedundantTest} for what this means for the (now
|
||||||
|
* unnecessary, but harmless) advice to {@code @ImportAutoConfiguration(FlywayAutoConfiguration.class)}
|
||||||
|
* yourself.
|
||||||
|
*/
|
||||||
|
@DataJpaTest
|
||||||
|
class FlywayRunsByDefaultTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationContext ctx;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void flywayAutoConfigurationBeansArePresentWithNoExplicitImportAnywhere() {
|
||||||
|
assertThat(ctx.getBeanNamesForType(org.flywaydb.core.Flyway.class)).isNotEmpty();
|
||||||
|
assertThat(ctx.containsBean("flywayInitializer")).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void theMigrationActuallyRanAgainstTheSubstitutedDatabase() throws Exception {
|
||||||
|
// Flyway's own history table always carries a bookkeeping row at installed_rank = -1
|
||||||
|
// ("<< Flyway Schema History table created >>") ahead of the real migration rows, and
|
||||||
|
// both the table name and every column name are stored quoted and lowercase -- H2's
|
||||||
|
// default unquoted-identifier folding (to uppercase) does not apply to any of them.
|
||||||
|
try (Connection connection = dataSource.getConnection();
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
ResultSet rs = statement.executeQuery(
|
||||||
|
"select \"installed_rank\", \"version\", \"description\", \"success\" "
|
||||||
|
+ "from \"flyway_schema_history\" where \"installed_rank\" = 1")) {
|
||||||
|
assertThat(rs.next()).isTrue();
|
||||||
|
String version = rs.getString(2);
|
||||||
|
String description = rs.getString(3);
|
||||||
|
boolean success = rs.getBoolean(4);
|
||||||
|
System.out.println("flyway_schema_history row: version=" + version
|
||||||
|
+ " description=" + description + " success=" + success);
|
||||||
|
assertThat(version).isEqualTo("1");
|
||||||
|
assertThat(description).isEqualTo("create product");
|
||||||
|
assertThat(success).isTrue();
|
||||||
|
assertThat(rs.next()).isFalse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
-52
@@ -1,52 +0,0 @@
|
|||||||
package com.ankurm.datajpa;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
|
||||||
import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest;
|
|
||||||
import org.springframework.boot.flyway.autoconfigure.FlywayAutoConfiguration;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.Statement;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The one-line fix for {@link FlywayDoesNotRunUnderPlainDataJpaTestTest}: pull
|
|
||||||
* FlywayAutoConfiguration into the slice yourself. Once it is in the context, Boot's own
|
|
||||||
* schema-management detection sees it, flips Hibernate's ddl-auto back to {@code none}, and the
|
|
||||||
* real migration runs against the same substituted (here, H2) DataSource.
|
|
||||||
*/
|
|
||||||
@DataJpaTest
|
|
||||||
@ImportAutoConfiguration(FlywayAutoConfiguration.class)
|
|
||||||
class FlywayRunsWhenExplicitlyImportedTest {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private DataSource dataSource;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void flywayHistoryTableProvesTheMigrationRanThisTime() throws Exception {
|
|
||||||
// Flyway's own history table always carries a bookkeeping row at installed_rank = -1
|
|
||||||
// ("<< Flyway Schema History table created >>") ahead of the real migration rows --
|
|
||||||
// easy to miss if a query only reads the first row back, which is what an earlier draft
|
|
||||||
// of this test did. The real V1 migration is installed_rank = 1.
|
|
||||||
try (Connection connection = dataSource.getConnection();
|
|
||||||
Statement statement = connection.createStatement();
|
|
||||||
ResultSet rs = statement.executeQuery(
|
|
||||||
"select \"installed_rank\", \"version\", \"description\", \"success\" "
|
|
||||||
+ "from \"flyway_schema_history\" where \"installed_rank\" = 1")) {
|
|
||||||
assertThat(rs.next()).isTrue();
|
|
||||||
String version = rs.getString(2);
|
|
||||||
String description = rs.getString(3);
|
|
||||||
boolean success = rs.getBoolean(4);
|
|
||||||
System.out.println("flyway_schema_history row: version=" + version
|
|
||||||
+ " description=" + description + " success=" + success);
|
|
||||||
assertThat(version).isEqualTo("1");
|
|
||||||
assertThat(description).isEqualTo("create product");
|
|
||||||
assertThat(success).isTrue();
|
|
||||||
assertThat(rs.next()).isFalse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user