Issue
I am currently trying to deploy my Spring Boot app to GCP, however I receive an unable to detect database type error upon doing so. The process for deploying is as follows, I am using the Google Cloud SDK shell and deploying with the command: "gcloud app deploy". The GCP project I am deploying to already contains the MySql database instance. Note that running the Spring Boot app locally and connecting to the GCP database works fine, but actually deploying the app to GCP causes some errors.
For context, here are my applications.properties and pom.xml files.
application.properties:
#spring.cloud.gcp.sql.enabled=false
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://PUBLIC_IP_ADDRESS_FOR_GCP_DATABASE/sparks
spring.datasource.username=root
spring.datasource.password=******
spring.session.store-type=jdbc
spring.session.jdbc.initialize-schema=always
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>2.6.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>sparks</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sparks</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<!-- <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-sql-mysql</artifactId>
<version>1.2.8.RELEASE</version>
</dependency> -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180130</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.javatuples</groupId>
<artifactId>javatuples</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
First line of error logs:
2022-10-14 05:59:51 default[20221014t015109] 2022-10-14 05:59:51.808 ERROR 11 --- [ main] o.s.b.web.embedded.tomcat.TomcatStarter : Error starting Tomcat context.
Exception: org.springframework.beans.factory.UnsatisfiedDependencyException. Message:
Error creating bean with name 'sessionRepositoryFilterRegistration' defined in class path resource [org/springframework/boot/autoconfigure/session/SessionRepositoryFilterConfiguration.class]:
Unsatisfied dependency expressed through method 'sessionRepositoryFilterRegistration' parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.session.JdbcSessionConfiguration$SpringBootJdbcHttpSessionConfiguration':
Unsatisfied dependency expressed through method 'setTransactionManager' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'transactionManager' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]:
Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jdbcSessionDataSourceScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/session/JdbcSessionConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [org.springframework.boot.autoconfigure.session.JdbcSessionDataSourceScriptDatabaseInitializer]:
Factory method 'jdbcSessionDataSourceScriptDatabaseInitializer' threw exception; nested exception is java.lang.IllegalStateException: Unable to detect database type
Error Logs in Full:
As for what I have already tried:
I read on this page that spring.datasource.url will be ignored unless I use "spring.cloud.gcp.sql.enabled=false", however this solution seemed to have no effect. I have the commented out line in my application.properties and dependency at the bottom of the pom.xml.
I have tried using cloud run with this tutorial and the error messages turned out the same. My thought process behind using this method was that somehow the server did not have access being deployed on the gcp project as opposed to my local computer, which I have as an approved ip address on the mysql gcp instance.
I have tried using a few different variations of the applications.properties file as described here, however this only seemed to cause more issues.
I am new to GCP and Spring boot, and this is my first time posting on stack overflow. Any advice is appreciated both on my posts quality and how I might fix this issue. I would sincerely appreciate any and all feedback, and I thank anyone who takes the time to read my post. Additionally, if anymore information would help for the resolution of my post I would gladly provide it, so please let me know feedback in that area as well.
Thank you for your time.
EDIT: As per the comment below, I want to clarify that I believe I am missing a dependency of some kind or that my application.properties needs additional information in order to work on GCP, and so I am looking if anyone has advice of things to add or change in this regard. I also want to reiterate that my app works with the GCP database I have setup when I run the server locally with the current pom.xml and application.properties.
EDIT #2: After some more investigation I believe that for some reason connecting to the sql gcp server with the spring.datasource.url is somehow different and is the cause of this issue. This post seems too have a similar issue with a solution although it doesn't seem to have solved my problem or I am just replicating the change incorrectly.
Solution
My god I've done it. Somehow through use of collecting my thoughts on this post and a combination of the methods below I got it to deploy. Specifically, I added these following two dependencies to my pom.xml:
As well as editing my application.properties as so:
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://PUBLIC_IP_ADDRESS/sparks
spring.datasource.username=root
spring.datasource.password=******
spring.cloud.gcp.project-id=PROJECT_ID_FROM_GCP_PROJECT
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.cloud.gcp.sql.instance-connection-name=CONNECTION_NAME_FROM_GCP_DATABASE
spring.cloud.gcp.sql.database-name=sparks
spring.cloud.gcp.logging.enabled=true
spring.sql.init.mode=always
This is what let the gcloud app deploy work. I hope that somehow my ramblings help someone as dumb and inept as myself deploy their spring app to GCP and properly detect their database.
Answered By - Edjoe
Answer Checked By - Dawn Plyler (JavaFixing Volunteer)