I'm using Eclipse for my Spring Boot application. I want to use Docker container for my jdk and mysql.
The problem is container(Spring) refused to connect to container(mysql). FYI, I run container(mysql) in other software and it works fine. I can access the database.
I tried to run docker compose down --rmi all and run again docker compose up --build but same error appears
I keep getting these errors in my logs:
Could not create connection to database server. Attempted reconnect 3 times. Giving up.
Failed to initialize JPA EntityManagerFactory: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution [Could not create connection to database server. Attempted reconnect 3 times. Giving up.
Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution [Could not create connection to database server. Attempted reconnect 3 times. Giving up.
Appreciate if someone can help me . I've been stuck for week now for this issue .
Dockerfile
FROM maven:3.9.6-eclipse-temurin-21 AS build
WORKDIR /home/app
COPY ./pom.xml /home/app/pom.xml
COPY ./src/main/java/project/ProjectApplication.java /home/app/src/main/java/project/ProjectApplication.java
RUN mvn -f /home/app/pom.xml clean package
COPY . /home/app
RUN mvn -f /home/app/pom.xml clean package
# Set the Spring Boot datasource URL
ENV SPRING_DATASOURCE_URL=jdbc:mysql://docker-mysql:3306/restapidb?autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
FROM openjdk:21-slim-bullseye
VOLUME /tmp
EXPOSE 8080
COPY --from=build /home/app/target/*.jar app.jar
ENTRYPOINT [ "sh", "-c", "java -jar /app.jar"]
docker-compose.yml
version: '3.8'
services:
docker-mysql:
image: mysql:8.0
container_name: mysqleclipse
environment:
MYSQL_ROOT_PASSWORD: Pass1234
MYSQL_DATABASE: testdb
MYSQL_USER: testuser
MYSQL_PASSWORD: Pass1234
ports:
- "3306:3306" # Map port 3306 on the host to port 3306 on the container
spring-app:
build:
context: .
dockerfile: Dockerfile
container_name: springbootjdbc
ports:
- "8080:8080" # Map port 8080 on the host to port 8080 on the container
depends_on:
- docker-mysql
Pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>my.com.exim</groupId>
<artifactId>jdbc-project9</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>jdbc-project9</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
</plugin>
</plugins>
</build>
</project>
application.properties
server.port=8080
spring.datasource.url=jdbc:mysql://docker-mysql:3306/restapidb?autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
spring.datasource.username=testuser
spring.datasource.password=Pass1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
HelloWorld.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
@Component
public class HelloWorld implements CommandLineRunner {
private final JdbcTemplate jdbcTemplate;
@Autowired
public HelloWorld(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public void run(String... args) throws Exception {
testJdbcConnection();
}
private void testJdbcConnection() {
try {
// Perform a simple query to test the connection
Integer count = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM tables", Integer.class);
System.out.println("Connection successful! Rows in the table: " + count);
} catch (Exception e) {
System.err.println("Error testing JDBC connection: " + e.getMessage());
}
}
}