zonkyio / embedded-database-spring-test

A library for creating isolated embedded databases for Spring-powered integration tests.
Apache License 2.0
399 stars 37 forks source link

Error creating bean with name 'zonkyPostgresDatabaseProvider' #188

Closed ssprang closed 2 years ago

ssprang commented 2 years ago

Hi! πŸ‘‹πŸ» I'm trying to upgrade to io.zonky.test:embedded-database-spring-test:2.1.1 from version 1.6.3 and I'd like to use the postgresql testcontainer. It's a spring boot, maven, kotlin project using flyway for migrations (Spring boot version 2.6.0, flyway-spring-test 7.0.0, flyway-core 8.0.4) and I have this in my test application.properties:

zonky.test.database.postgres.docker.image=postgres:12-alpine
zonky.test.database.type=postgres
zonky.test.database.provider=docker

I can see that the docker container starts ok, the flyway migrations run ok but the application fails to start due to this:

Error creating bean with name 'zonkyPostgresDatabaseProvider' defined in class path resource [io/zonky/test/db/config/EmbeddedDatabaseAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.zonky.test.db.provider.DatabaseProvider]: Factory method 'zonkyPostgresDatabaseProvider' threw exception; nested exception is io.zonky.test.db.config.MissingProviderDependencyException: You have to add the following dependency to your project: 'io.zonky.test:embedded-postgres' (https://mvnrepository.com/artifact/io.zonky.test/embedded-postgres)

The project shouldn't use the zonkyPostgresDatabaseProvider in the first place.. But if I do as directed by the log message and add embedded-postgres to my dependencies, then the application fails to start with:

Error creating bean with name 'openTablePostgresDatabaseProvider' defined in class path resource [io/zonky/test/db/config/EmbeddedDatabaseAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.zonky.test.db.provider.DatabaseProvider]: Factory method 'openTablePostgresDatabaseProvider' threw exception; nested exception is io.zonky.test.db.config.MissingProviderDependencyException: You have to add the following dependency to your project: 'com.opentable.components:otj-pg-embedded' (https://mvnrepository.com/artifact/com.opentable.components/otj-pg-embedded)

So it's like the application is trying to start all database providers even though I have specifically requested docker and postgres.

It makes no difference if I move the settings from application.properties to the @AutoConfigureEmbeddedDatabase annotation.

@AutoConfigureEmbeddedDatabase(provider = AutoConfigureEmbeddedDatabase.DatabaseProvider.DOCKER, type = AutoConfigureEmbeddedDatabase.DatabaseType.POSTGRES)

Does anyone know what I'm doing wrong?

tomix26 commented 2 years ago

Hi @ssprang, thanks for the question. It seems to me that something in your application (a component, bean postprocessor, etc.) is enforcing initialization on these lazy beans. So please make sure that you are not autowiring or referencing any of these database providers in your application. And that even in some more generic way, e.g. autowiring List<DatabaseProvider> providers can also cause this problem. Additionally, make sure you are not using any processor or other feature that enforces early initialization of spring beans.

ssprang commented 2 years ago

Ah, thank you! πŸ™πŸ» I debugged, put a breakpoint on io.zonky.test.db.config.EmbeddedDatabaseAutoConfiguration#zonkyPostgresDatabaseProvider and found a bad class in the project initializing all beans, just like you suspected. Also, thanks for the quick feedback!! ⭐ πŸ˜‰