Spring Boot on Google Cloud SQL - org.hibernate.Hi

2019-08-17 04:22发布

When I run my program in localhost connecting remotely to Google Cloud SQL (MySQL), it works. All the necessary IAM permission are in place once the program is deployed in the Google App Engine, it causes the error:

org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set. Logs Below:

Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:100) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final] at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:54) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final] at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:137) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final] at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final] at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:88) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final] at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:254) ~[hibernate-core-5.0.12.Final.jar!/:5.0.12.Final] ... 41 common frames omitted

POM File:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.myapi</groupId>
	<artifactId>myapi</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>myapi</name>
	<description>My API</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>

		<INSTANCE_CONNECTION_NAME>myapi:asia-south1:myapidb</INSTANCE_CONNECTION_NAME>
		<user>root</user>
		<password>complicated password</password>
		<database>myapidb</database>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework.security.oauth</groupId>
			<artifactId>spring-security-oauth2</artifactId>
			<version>2.2.1.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>

		<!--<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
			&lt;!&ndash;<version>8.0.8-dmr</version>&ndash;&gt;
		</dependency>-->

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.42</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-jwt</artifactId>
		</dependency>

		<!--<dependency>
			<groupId>com.google.cloud.sql</groupId>
			<artifactId>mysql-socket-factory-connector-j-6</artifactId>
			<version>1.0.4</version>
		</dependency>-->
		<dependency>
			<groupId>com.google.cloud.sql</groupId>
			<artifactId>mysql-socket-factory</artifactId>
			<version>1.0.4</version>
		</dependency>

		<!--<dependency>
			<groupId>com.google.appengine</groupId>
			<artifactId>appengine-maven-plugin</artifactId>
			<version>1.9.63</version>
		</dependency>-->

		<dependency>
			<groupId>com.google.cloud.tools</groupId>
			<artifactId>appengine-maven-plugin</artifactId>
			<version>1.3.2</version>
		</dependency>



		<!--<dependency>
			<groupId>com.google.cloud.sql</groupId>
			<artifactId>mysql-socket-factory</artifactId>
			&lt;!&ndash;<version>1.0.4</version>&ndash;&gt;
			<version>1.0.5</version>
		</dependency>-->

		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
			<version>23.6-jre</version>
		</dependency>


		<!--<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
		</dependency>-->

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>


		<!--dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-gcp-starter-sql</artifactId>
			<version>1.0.0.M1</version>
		</dependency>-->

		<dependency>
			<groupId>com.fasterxml.jackson.datatype</groupId>
			<artifactId>jackson-datatype-jsr310</artifactId>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.module</groupId>
			<artifactId>jackson-module-parameter-names</artifactId>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.datatype</groupId>
			<artifactId>jackson-datatype-jdk8</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-jpa</artifactId>
		</dependency>

		<!--<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-gcp</artifactId>
			<version>1.0.0.M2</version>
		</dependency>-->


	</dependencies>

	<!--<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/libs-milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>-->
	<!--<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>-->
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

3条回答
甜甜的少女心
2楼-- · 2019-08-17 04:38

For me it was nothing to do with the hibernate setup.

In the stackdriver's log there was a clear error message to enable the Cloud SQL Admin API:

java.lang.RuntimeException: The Google Cloud SQL API is not enabled for project [<project>]. Please use the Google Developers Console to enable it: https://console.cloud.google.com/apis/api/sqladmin/overview?project=<project>

A similar error message (as in OP's post) happens when the JDBC URL is wrong and your app can't connect to the Cloud SQL database.

查看更多
Ridiculous、
3楼-- · 2019-08-17 04:45

Your JDBC connection string is probably incorrect for App Engine, and Hibernate is unable to figure out the dialect automatically. Note that the connection string for connecting locally is different than when running on App Engine. See docs.

  <system-properties>
    <property name="cloudsql" value="jdbc:google:mysql://${INSTANCE_CONNECTION_NAME}/${database}?user=${user}&amp;password=${password}" />
    <property name="cloudsql-local" value="jdbc:mysql://google/${database}?useSSL=false&amp;cloudSqlInstance=${INSTANCE_CONNECTION_NAME}&amp;socketFactory=com.google.cloud.sql.mysql.SocketFactory&amp;user=${user}&amp;password=${password}" />
  </system-properties>

Also, since you are using Spring Boot, you might want to consider using Spring Cloud GCP for connecting to Cloud SQL, which has support for automatically detecting App Engine and generating the correct connection string.

查看更多
兄弟一词,经得起流年.
4楼-- · 2019-08-17 04:50

I have not myself worked with Spring Boot and Cloud SQL, but according to some external sources like [A] or [B], you should have a file called application.properties in the directory src/main/resources of your application, and there, you should set some spring properties like:

database=mysql
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://google/<DB_NAME>?cloudSqlInstance=<INSTANCE_CONNECTION_NAME>&socketFactory=com.google.cloud.sql.mysql.SocketFactory
spring.datasource.username=<USERNAME>
spring.datasource.password=<PASSWORD>

Make sure that you are setting the names properly in this application.properties file, and also in the pom.xml file.


查看更多
登录 后发表回答