on AWS - could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet aws - mysql

I have this (common) problem with my DB access. But in my case, I dont find the right answere...
Created a very basic MySql DB and Spring Boot App accessing it.
On my localhost it runs smooth.
Then I dumped the local DB. Inserted it into the AWS-MySql DB.
And deployed the Spring-Boot app with Docker to my EC2.
Everything is well.
But on using the AWS MySQL all REST Endpoints return:
status 500
could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
For me it looks like all the same as it was on localhost.
What did I miss?

I found the cause. I know a solution.
BUT I cant accept to not to know how it happend:
My POJOs are defined by Classname only (no Table="" Metadata decortion)
On my local machine it runs well.
The SQL query is: "... 'Dbname'.'tablename' ... "
Dockerized on AWS on the RDS Mysql.
The SQL query is: "... 'Dbname'.'TableName' ... "
And then the of course the query fails.
My configs:
properties:
#Hibernate (Spring-JPA)
hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
POM:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.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>
<spring-cloud-services.version>1.5.0.RELEASE</spring-cloud-services.version>
<spring-cloud.version>Dalston.SR3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>io.pivotal.spring.cloud</groupId>
<artifactId>spring-cloud-services-starter-service-registry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.pivotal.spring.cloud</groupId>
<artifactId>spring-cloud-services-dependencies</artifactId>
<version>${spring-cloud-services.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
So obviously my NamingStrategy settings will be ignored or overriden in local or aws.
But at this point I could need some help.
PS: And why I cant find any useful documentatins about the Hibernate naming strategy settings?!? e.g.: strat-setting-A => TableName -> TABLE_NAME etc...
Why do I have to read the code to understand this? (T.T)
EDIT:
Hooray! I have the cause.
My local db config is diffrent. Well its by default: lower_case_table_names=1
So it just ignores CamelCase. But on aws it seems to be set to 0 Which means it takes care of camel case names.
So soultion is easy: Setting my naming strategy to lowercase only!
Just WHERE do I find the docs which config is right?? :-)
Well anyway... better no docs then wrong docs!
SOLUTION:
2 Options:
1 - Configuring the POJOs manually with #Table() decorator.
2 - Removing the hibernate naming setting from the properties (or change it to what ever needed)
PS: Iam still interessted into all setting possibilites if someone know a good doc.

Related

Adding feign-client dependency is causing error! I cannot start the application

I only added this dependency and i am not able to start my application.
Can you explain why it is happening?
Without this dependency the spring-boot application is working. I tried to use 2.5.4 and 2.4.2 versions of spring-boot.
It is causing the following error:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
Caused by: java.io.FileNotFoundException: class path resource [org/springframework/boot/autoconfigure/web/ServerPropertiesAutoConfiguration.class] cannot be opened because it does not exist
I was facing same issue and I resolved it . in your pom , remove version from all spring-cloud dependency and then add below thing in your pom :
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2021.0.1</spring-cloud.version>
</properties>
and
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Note : please pick version as per your requirements. thanks.

Error:org.apache.commons.logging.LogFactoryjava.lang.NoClassDefFoundError for application build with micronaut-bom1.2.10, graal19.2.1 & aws-sdk2.10.56

Created an application using micronaut bom 1.2.10 version, along with software.amazon.awssdk:lambda:2.10.56 & software.amazon.awssdk:s3:2.10.56 dependencies which had functionality to retrieve data from s3 storage and used graal 19.2.1 to create a native image.
The native image is successfully created but when i try to access the endpoint it fails for below exception:
failed: org.apache.commons.logging.LogFactoryjava.lang.NoClassDefFoundError: org.apache.commons.logging.LogFactory
and series of exceptions with specifically while creating S3 client.
The exception also had failure at below point:
failed: Could not initialize class software.amazon.awssdk.http.apache.internal.conn.SdkTlsSocketFactoryjava.lang.NoClassDefFoundError: Could not initialize class software.amazon.awssdk.http.apache.internal.conn.SdkTlsSocketFactory
Code for S3Client :
S3Client s3Client = S3Client.builder().region(getRegion()).build();
build-native-image.sh
${GRAALVM_HOME}/bin/native-image --no-server -cp example-function-*-all.jar
-H:IncludeResources="git.properties"
-H:IncludeResources="logback.xml"
-H:IncludeResources="application.properties" \
So this issue was resolved by adding below configuration in build.gradle:
allprojects {
configurations {
all {
exclude(group = "commons-logging")
}
}
}
and in the dependencies added:
compile group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.7.30'
I hope this helps.
I faced the same issue, when running tests, with the exact same NoClassDefFoundError but when using AWS sts and secretsmanager libraries. I could actually get it to work by just including the jcl-over-slf4j dependency, while the error happened when using the slf4j-api dependency. I did not need to exclude commons-logging. Snippet of dependency in maven pom.xml that worked:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>2.17.89</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>secretsmanager</artifactId>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>sts</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>
</dependencies>

Integration Test with Couchbase container

I am writing an integration test, which should use a couchbase container.
Using org.testcontainers.couchbase.CouchbaseContainer with
#Rule
public CouchbaseContainer couchbaseContainer = new CouchbaseContainer()
.withNewBucket(DefaultBucketSettings.builder()
.enableFlush(true)
.name("xxx").password("123456")
.quota(100)
.type(BucketType.COUCHBASE)
.build());
I get an error:
Caused by: com.couchbase.client.java.error.InvalidPasswordException: Passwords for bucket "xxx" do not match.
at com.couchbase.client.java.CouchbaseAsyncCluster$OpenBucketErrorHandler.call(CouchbaseAsyncCluster.java:651)
When I looked inside the container, I could see that bucket whose created without the user. (In order to be able to use that bucket, a user, with the same name must be created, and user's password is actually password to enter the bucket).
While not providing UserSettings, withNewBucket method generates user with all roles. I tried to add custome UserSettings, but the result was the same - user wasn't created.
Using
<dependency>
<groupId>com.couchbase.client</groupId>
<artifactId>couchbase-client</artifactId>
<version>1.4.13</version>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>couchbase</artifactId>
<version>1.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>jdbc</artifactId>
<version>1.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.couchbase.client</groupId>
<artifactId>java-client</artifactId>
<version>2.5.9</version>
</dependency>
Any help is appreciated.

Spring Boot on Google Cloud SQL - org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set

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>
<!–<version>8.0.8-dmr</version>–>
</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>
<!–<version>1.0.4</version>–>
<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>
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.
A - Community Tutorial on how to run Spring Boot with Cloud SQL on
GAE Flexible
B - Guide on how to connect to Cloud SQL using Spring
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}&password=${password}" />
<property name="cloudsql-local" value="jdbc:mysql://google/${database}?useSSL=false&cloudSqlInstance=${INSTANCE_CONNECTION_NAME}&socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=${user}&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.
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.
Add in your pom.xml:
<dependency>
<groupId>com.google.cloud.sql</groupId>
<artifactId>mysql-socket-factory-connector-j-8</artifactId>
<version>1.0.15</version>
</dependency>
jdbc:mysql:///<DATABASE_NAME>?cloudSqlInstance=<INSTANCE_CONNECTION_NAME>&socketFactory=com.google.cloud.sql.mysql.SocketFactory&useSSL=false&user=<USER_NAME>&password=<USER_PASSWORD>
spring:
data:
rest:
base-path: /api
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
For the driver use this new one: com.mysql.cj.jdbc.Driver ,
about the SocketFactory, it gets your instances IP address base on the provided cloudSqlInstance

Replace hsqldb with MySQL

I have a Spring REST project configured with hsqldb.
I would like to change it to MySQL.
I have MySQL server installed and running, but I don't know how to modify this pom:
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
PS.: Project im talking about comes as a source code for 'Spring REST' book:
http://www.apress.com/9781484208243
source code download link:
http://www.apress.com/downloadable/download/sample/sample_id/1704/
As far I see you are using Spring Boot on this, so you can easy change the databases changing the drivers dependencies from:
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
To
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
The driver version will be version on parent pom.
Then specify the parameters on properties
spring.datasource.url=jdbc:mysql://localhost:port/yourdb
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver # we can ommit this if we want, Spring Boot will deduce based on the classpath
For more configuration on databases you can see the properties available on appendix here