Hi
We tried to use Spring Boot & TestContainers integration added in Spring Boot 3.1.0.
We used example from the reference documentation:
public interface MyContainers {
@Container
MongoDBContainer mongoContainer = new MongoDBContainer("mongo:5.0");
@Container
Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>("neo4j:5");
}
So we created an interface with our container declaration:
public interface ProjectContainers {
@Container
GenericContainer<?> mysql = new MySQLContainer("mysql:8");
}
Then we created class-configuration:
@TestConfiguration(proxyBeanMethods = false)
@ImportTestcontainers(ProjectContainers.class)
public class ContainerConfiguration {
}
and finally our integration test:
@SpringBootTest(classes = ContainerConfiguration.class)
@Testcontainers
public class OrderServiceTest {
@Autowired
OrderService orderService;
@Test
void save_success() {
Order order = new Order();
orderService.save(order);
}
However our test failed with exception:
Caused by: org.hibernate.HibernateException: Unable to determine Dialect without JDBC metadata (please set 'javax.persistence.jdbc.url', 'hibernate.connection.url', or 'hibernate.dialect')
at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:188) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:87) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:274) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:34) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:119) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:264) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
Comment From: eddumelendez
Use MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8"); and add @ServiceConnection. Look at the tip at the end of https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.testing.testcontainers.at-development-time.importing-container-declarations
Comment From: sergey-morenets
Hi @eddumelendez
Thank you for the quick response. You're correct. Adding @ServiceConnection resolves this issue. However I guess adding code that already has @ServiceConnection makes code examples more obvious and clear.
The same relates to declaring containers as Spring beans. Here's an example from the documentation:
@TestConfiguration(proxyBeanMethods = false)
public class MyContainersConfiguration {
@Bean
public MongoDBContainer monogDbContainer(DynamicPropertyRegistry properties) {
MongoDBContainer container = new MongoDBContainer("mongo:5.0");
properties.add("spring.data.mongodb.host", container::getHost);
properties.add("spring.data.mongodb.port", container::getFirstMappedPort);
return container;
}
}
The documentation states that "A typical configuration would look like this". However Spring Boot fails to use it because it doesn't have @ServiceConnection annotation on the bean declaration.
Comment From: eddumelendez
Are you using it at development time just like the docs state? If no, keep using
@DynamicPropertySource
static void properties(DynamicPropertyRegistry registry) {
registry.add("spring.data.mongodb.host", container::getHost);
registry.add("spring.data.mongodb.port", container::getFirstMappedPort);
}
I think there is a confusion about the different usage
Comment From: wilkinsona
In the docs, we don't know how MyContainers will be used. You could make your test class implement MyContainers and then reference those containers in a @DynamicPropertySource. Alternatively, you might need @ServiceConnection. The tip at the end of this section is intended to address that.
That said, this has caused some confusion before so we probably need to do something here, I'm just not quite sure what.
/cc @quaff
Comment From: quaff
@wilkinsona I think we should add @ServiceConnection, and add a tip states that it could be removed if @DynamicPropertySource is using.