Spring Boot DB Migration with Flyway to MySQL - mysql

I have a Gradle Spring Boot web application that migrates from H2 to PostgreSQL using Flyway. I am trying to convert this to migrate from H2 to MySQL. The build.gradle file is:
buildscript {
ext {
springBootVersion = '1.3.0.RELEASE'
}
repositories {
maven { url "http://repo.spring.io/milestone" }
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'war'
war {
baseName = 'demo'
version = '0.0.1-SNAPSHOT'
archiveName = 'demo.war'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
maven { url "http://repo.spring.io/milestone" }
mavenCentral()
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-actuator")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile("org.springframework.boot:spring-boot-starter-security")
compile("com.h2database:h2")
compile("org.postgresql:postgresql:9.4-1201-jdbc41")
compile("org.flywaydb:flyway-core")
testCompile("org.springframework.boot:spring-boot-starter-test")
}
eclipse {
classpath {
containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7'
}
}
task wrapper(type: Wrapper) {
gradleVersion = '1.12'
}
There is an application.yml file:
error:
whitelabel:
enabled: false
amazon:
associate_id: habuma-20
spring:
jpa:
hibernate:
ddl-auto: none
---
spring:
profiles: production
datasource:
url: jdbc:postgresql://localhost:5432/readinglist
username: habuma
password:
jpa:
database-platform: org.hibernate.dialect.PostgreSQLDialect
In build.gradle, I replaced
compile("org.postgresql:postgresql:9.4-1201-jdbc41")
with
compile("mysql:mysql-connector-java:5.1.5")
and changed application.yml to
error:
whitelabel:
enabled: false
amazon:
associate_id: habuma-20
spring:
jpa:
hibernate:
ddl-auto: none
---
spring:
profiles: production
datasource:
url: jdbc:mysql://localhost:3306/readinglist
username: root
password: ******
jpa:
database-platform: org.hibernate.dialect.MySQL5Dialect
To get the "production" profile I set an environment variable SPRING_PROFILES_ACTIVE=production. Then run with the command java -jar build/libs/demo.war. When the application tries to boot up I get the following error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(org.springframework.security.config.annotation.ObjectPostProcessor,java.util.List) throws java.lang.Exception;
nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityConfig': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private readinglist.ReaderRepository readinglist.SecurityConfig.readerRepository;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'readerRepository': Cannot create inner bean '(inner bean)#1c65a791' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager';
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#1c65a791': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed;
nested exception is org.flywaydb.core.api.FlywayException: Validate failed. Migration Checksum mismatch for migration 1
I'm not sure what the solution to this Checksum mismatch is.

Related

How to integrate mysql or mongodb to grails 3.2.10

I'm about start with a web application project and I am trying to integrate Mysql into Grails 3. All of the online tutorials show us to change the DataSource file which does not currently (there is Application.yml).
I tried changing the Application.yml as given in the official documentation, but it gives me a big error. Its a new project and has no other changes to it. I've used grails 2.4 previously, it was really easy with that and now I'm thinking of changing back.
Change:
dataSource :
pooled : true
dbCreate : "update"
url : "jdbc:mysql://localhost:3306/my_database"
driverClassName : "com.mysql.jdbc.Driver"
dialect : org.hibernate.dialect.MySQL5InnoDBDialect
username : "username"
password : "password"
properties :
jmxEnabled : true
initialSize : 5
maxActive : 50
minIdle : 5
maxIdle : 25
maxWait : 10000
maxAge : 10 * 60000
timeBetweenEvictionRunsMillis : 5000
minEvictableIdleTimeMillis : 60000
validationQuery : "SELECT 1"
validationQueryTimeout : 3
validationInterval : 15000
testOnBorrow : true
testWhileIdle : true
testOnReturn : false
jdbcInterceptors : "ConnectionState;StatementCache(max=200)"
defaultTransactionIsolation :
java.sql.Connection.TRANSACTION_READ_COMMITTED
the error I get:
/usr/lib/jvm/java-8-oracle/bin/java -XX:+TieredCompilation -
XX:TieredStopAtLevel=1 -XX:CICompilerCount=3 -Dfile.encoding=UTF-8 -
classpath /home/nischit/.gradle/caches/modules-2/files-
2.1/org.grails/grails-
shell/3.2.10/c6b000bbb8ac369a9be062f08e8a0a8d3f85705/grails-shell-
3.2.10.jar:/home/nischit/.gradle/caches/modules-2/files-
2.1/org.slf4j/slf4j-
simple/1.7.25/8dacf9514f0c707cbbcdd6fd699e8940d42fb54e/slf4j-simple-
1.7.25.jar:/home/nischit/.gradle/caches/modules-2/files-
2.1/org.codehaus.plexus/plexus-component-api/1.0-alpha-
33/7d9560effcadf867937ac6885d0d1045ea98ab59/plexus-component-api-1.0-
alpha-33.jar:/home/nischit/.gradle/caches/modules-2/files
Running application...
2017-10-02 01:42:14.120 ERROR --- [ost-startStop-1]
o.s.b.c.embedded.tomcat.TomcatStarter : Error starting Tomcat
context. Exception:
org.springframework.beans.factory.BeanCreationException. Message:
Error creating bean with name 'grailsCacheFilter': Cannot create
inner bean '(inner bean)#17d4fdc1' of type
[grails.plugin.cache.web.filter.
simple.MemoryPageFragmentCachingFilter]
while setting bean property 'filter'; nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name '(inner bean)#17d4fdc1': Unsatisfied
dependency expressed through method 'setUrlMappingsHandlerMapping'
parameter 0; nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'urlMappingsHandlerMapping':
Unsatisfied dependency expressed through method
'setWebRequestInterceptors' parameter 0; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'openSessionInViewInterceptor': Cannot
resolve reference to bean 'hibernateDatastore' while setting bean
property 'hibernateDatastore'; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'hibernateDatastore': Bean instantiation via
constructor failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [org.grails.orm.hibernate.HibernateDatastore]:
Constructor threw exception; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'dataSource': Cannot resolve reference to
bean 'dataSourceLazy' while setting constructor argument; nested
exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'dataSourceLazy': Cannot resolve
reference to bean 'dataSourceUnproxied' while setting constructor
argument; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at grails.boot.GrailsApp.run(GrailsApp.groovy:83)
at grails.boot.GrailsApp.run(GrailsApp.groovy:388)
at grails.boot.GrailsApp.run(GrailsApp.groovy:375)
at grails.boot.GrailsApp$run.call(Unknown Source)
at
org.codehaus.groovy.runtime.callsite.CallSiteArray.
defaultCall(CallSiteArray.java:48)
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'grailsCacheFilter': Cannot create
inner bean '(inner bean)#17d4fdc1' of type
[grails.plugin.cache.web.filter.simple.
MemoryPageFragmentCachingFilter] while setting bean property
'filter'; nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name '(inner bean)#17d4fdc1': Unsatisfied
dependency expressed through method 'setUrlMappingsHandlerMapping'
parameter 0; nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'urlMappingsHandlerMapping':
Unsatisfied dependency expressed through method
'setWebRequestInterceptors' parameter 0; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'openSessionInViewInterceptor': Cannot
resolve reference to bean 'hibernateDatastore' while setting bean
property 'hibernateDatastore'; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'hibernateDatastore': Bean instantiation via
constructor failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [org.grails.orm.hibernate.HibernateDatastore]:
Constructor threw exception; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'dataSource': Cannot resolve reference to
bean 'dataSourceLazy' while setting constructor argument; nested
exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'dataSourceLazy': Cannot resolve
reference to bean 'dataSourceUnproxied' while setting constructor
argument; nested exception is
org.springframework.beans.factory.BeanCreationException: Error c
reating bean with name 'dataSourceUnproxied': Initialization of bean
failed; nested exception is
org.springframework.beans.TypeMismatchException: Failed to convert
property value of type 'java.lang.String' to required type 'long' for
property 'maxAge'; nested exception is
java.lang.NumberFormatException: For input string: "10*60000"
at
org.springframework.beans.factory.support.
BeanDefinitionValueResolver.resolveInnerBean
(BeanDefinitionValueResolver.java:313)
Caused by:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name '(inner bean)#17d4fdc1': Unsatisfied
dependency expressed through method 'setUrlMappingsHandlerMapping'
parameter 0; nested exception is
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'urlMappingsHandlerMapping':
Unsatisfied dependency expressed through method
'setWebRequestInterceptors' parameter 0; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'openSessionInViewInterceptor': Cannot
resolve reference to bean 'hibernateDatastore' while setting bean
property 'hibernateDatastore'; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'hibernateDatastore': Bean instantiation via
constructor failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [org.grails.orm.hibernate.HibernateDatastore]:
Constructor threw exception; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'dataSource': Cannot resolve reference to
bean 'dataSourceLazy' while setting constructor argument; nested
exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'dataSourceLazy': Cannot resolve
reference to bean 'dataSourceUnproxied' while setting constructor
argument; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'dataSourceUnproxied': Initialization of bean
failed; nested exception is
org.springframework.beans.TypeMismatchException: Failed to convert
property value of type 'java.lang.String' to required type 'long' for
property 'maxAge'; nested exception is
java.lang.NumberFormatException: For input string: "10*60000"
at
org.springframework.beans.factory.annotation.
AutowiredAnnotationBeanPostProcessor
$AutowiredMethodElement.inject
(AutowiredAnnotationBeanPostProcessor.java:667)
Caused by:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'urlMappingsHandlerMapping':
Unsatisfied dependency expressed through method
'setWebRequestInterceptors' parameter 0; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'openSessionInViewInterceptor': Cannot
resolve reference to bean 'hibernateDatastore' while setting bean
property 'hibernateDatastore'; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'hibernateDatastore': Bean instantiation via
constructor failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [org.grails.orm.hibernate.HibernateDatastore]:
Constructor threw exception; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'dataSource': Cannot resolve reference to
bean 'dataSourceLazy' while setting constructor argument; nested
exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'dataSourceLazy': Cannot resolve
reference to bean 'dataSourceUnproxied' while setting constructor
argument; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'dataSourceUnproxied': Initialization of bean
failed; nested exception is
org.springframework.beans.TypeMismatchException: Failed to convert
property value of type 'java.lang.String' to required type 'long' for
property 'maxAge'; nested exception is
java.lang.NumberFormatException: For input string: "10*60000"
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':bootRun'.
Process 'command '/usr/lib/jvm/java-8-oracle/bin/java'' finished with
non-zero exit value 1
* Try:
Run with --stacktrace option to get the stack trace. Run with --info
or --debug option to get more log output.
| Error Failed to start server (Use --stacktrace to see the full
trace)
The problem is with the way you're trying to set the maxAge value on your data source:
Failed to convert property value of type 'java.lang.String' to
required type 'long' for property 'maxAge'; nested exception is
java.lang.NumberFormatException: For input string: "10*60000"
Try just setting a concrete value rather than a calculation.
If you are not very comfortable with YML standard then simply create a new file with name application.groovy, place it inside the conf directory and add the datasource block in that groovy file. Don't forget to remove the data source block from application.yml file.

Failing to start my spring boot application due to 'javax.sql.DataSource' that could not be found

I am a beginner in spring boot and am trying to write a simple spring boot application.
My folder structure is as follows:
-> Project
-> build.gradle
-> settings.gradle
-> src/main/java
-> package
-> Main.java
-> UserController.java
-> UserRespository.java
-> dto
-> User.java
->src/main/resouces
-> application.properties
My build.gradle is as follows :
buildscript {
repositories {
jcenter()
}
dependencies {
classpath(
'org.springframework.boot:spring-boot-gradle- plugin:1.5.6.RELEASE'
)
classpath('mysql:mysql-connector-java:5.1.34')
}
}
apply plugin: 'java'
apply plugin: 'spring-boot'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile(
'org.springframework.boot:spring-boot-starter-actuator',
'org.springframework.boot:spring-boot-starter-web',
'org.springframework.boot:spring-boot-starter-data-jpa'
)
compile('mysql:mysql-connector-java')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
The application.properties is as follows:
spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=jdbc:mysql://localhost:3306/user
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.database=MYSQL
spring.jpa.show-sql = true
My Main.java is as follows:-
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
#SpringBootApplication
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
};
}
I am able to successfully build the application. If I run the application , I get Unable to start application with the following stacktrace:
2017-08-14 20:43:02.976 WARN 27205 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2017-08-14 20:43:02.978 INFO 27205 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2017-08-14 20:43:03.007 INFO 27205 --- [ main] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-08-14 20:43:03.198 ERROR 27205 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration required a bean of type 'javax.sql.Data Source' that could not be found.
- Bean method 'dataSource' not loaded because #ConditionalOnProperty (spring.datasource.jndi-name) did not find property 'jndi-name'
- Bean method 'dataSource' not loaded because #ConditionalOnBean (types: org.springframework.boot.jta.XADataSourceWrapper; SearchStrategy: all) did not find any beans
Action:
Consider revisiting the conditions above or defining a bean of type 'javax.sql.DataSource' in your configuration.
I have checked the dependencies tree and can find both hibernate as well as mysql connector in it.
Have tried removing #EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) , in that case I get Cannot load driver class: com.mysql.jdbc.Driver
You should move the dto package inside into your Main.java class package, In your case it should be like src/main/java/package/dto
So when spring-boot scans, your entity will be visible to the scanner.
Make sure you have added the MySQL driver dependency
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>

How to use datasource conditionally in applicationContext.xml

I'm creating a GAE project with Spring which will also use cloud SQL. While testing this app in local I'm pointing to my local MySQL environment but when I'll deploy it to GAE, it will point to cloud SQL instance. So I want to configure my driverName in datasource bean depending on environment. To this we generally use following in our java code
if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Production) {
// Load the class that provides the new "jdbc:google:mysql://" prefix.
Class.forName("com.mysql.jdbc.GoogleDriver");
url = "jdbc:google:mysql://<your-project-id>:<your-instance-name>/<your-database-name>?user=root";
} else {
// Local MySQL instance to use during development.
Class.forName("com.mysql.jdbc.Driver");
url = "jdbc:mysql://127.0.0.1:3306/<your-database-name>?user=root";
}
Now I want to achieve the same in applicationcontext.xml using Spring Expression language. I haven't done this before and not able to achieve it. Please guide me. This is what I tried
<bean id="isDev" class="java.lang.Boolean">
<constructor-arg value="#{ systemProperties[environment.value] == SystemProperty.Environment.Value.Development ? true : false }" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="#{ isDev ? com.mysql.jdbc.Driver : com.mysql.jdbc.GoogleDriver }" />
.
.
.
But I'm getting exception, attaching a part of exception
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'feedbackFormController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.sandeepapplabs.custengage.services.FeedbackFormService com.sandeepapplabs.custengage.controllers.FeedbackFormController.feedbackFormService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'feedbackFormService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.sandeepapplabs.custengage.daos.FeedbackFormDAO com.sandeepapplabs.custengage.services.impl.FeedbackFormServiceImpl.feedbackFormDAO; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'feedbackFormDAO' defined in ServletContext resource [/WEB-INF/custengage-servlet.xml]: Cannot resolve reference to bean 'dataSource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in ServletContext resource [/WEB-INF/custengage-servlet.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is java.lang.NullPointerException
I believe you need to quote the class names to make them literals...
... 'com.mysql.jdbc.Driver' ...
However it is easier to use Spring Profiles](http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/beans.html#beans-definition-profiles-xml) and enable the profile you want.
You can use Spring profiles to change concrete bean classes. Let's say you have 2 profiles: "prod" and "dev". Your bean methods should have #Profile annotation as below:
#Configuration
public class AppConfig {
...
#Bean
#Profile("prod")
public Object prodDataSource() {
return new ...
}
#Bean
#Profile("dev")
public Object getDataSource() throws Exception {
return new ...
}
}
If you are using Maven, you can select profile through pom.xml:
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<spring.profile>dev</spring.profile>
</properties>
</profile>
<profile>
<id>prod</id>
<activation>
<activeByDefault>false</activeByDefault>
<property>
<name>prod</name>
</property>
</activation>
<properties>
<spring.profile>prod</spring.profile>
</properties>
</profile>
</profiles>
You can pass profile selection argument by -D like: mvn -Dprod clean compile test install
EDIT:
In application.properties following property selects profile:
spring.profiles.active=${spring.profile}

How to start spring-boot app without depending on Database?

I am using "Spring-boot + Hibernate4 + mysql" for my application. As part of which I have a requirement where my sprint-boot app should be able to start even when database is down. Currently it gives the below exception when I try to start my spring boot app without DB being up.
I researched a lot and found out that this exception has to do with hibernate.temp.use_jdbc_metadata_defaults property.
I tried setting this in "application.yml" of spring boot but this property's value is not being reflected at runtime.
Exception Stack Trace:
2014-05-25 04:09:43.193 INFO 59755 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
2014-05-25 04:09:43.250 WARN 59755 --- [ main] o.h.e.jdbc.internal.JdbcServicesImpl : HHH000342: Could not obtain connection to query metadata : Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
2014-05-25 04:09:43.263 INFO 59755 --- [ main] o.apache.catalina.core.StandardService : Stopping service Tomcat
Error starting ApplicationContext. To display the auto-configuration report enabled debug logging (start with --debug)
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:973)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:750)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:120)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:648)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:909)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:898)
at admin.Application.main(Application.java:36)
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:104)
at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:71)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:205)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:89)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:206)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:178)
at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1885)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1843)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:843)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:399)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:842)
at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:150)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:336)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
... 15 more
application.yml:
spring:
jpa:
show-sql: true
hibernate:
ddl-auto: none
naming_strategy: org.hibernate.cfg.DefaultNamingStrategy
temp:
use_jdbc_metadata_defaults: false
It was indeed a tough nut to crack.
After lot and lot of research and actually debugging the spring-boot, spring, hibernate, tomcat pool, etc to get it done.
I do think that it will save lot of time for people trying to achieve this type of requirement.
Below are the settings required to achieve the following requirement
Spring boot apps will start fine even if DB is down or there is no DB.
Apps will pick up the connections on the fly as DB comes up which means there is no need to restart the web server or redeploy the apps.
There is no need to start the tomcat or redeploy the apps, if DB goes down from running state and comes up again.
application.yml :
spring:
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/schema
username: root
password: root
continueOnError: true
initialize: false
initialSize: 0
timeBetweenEvictionRunsMillis: 5000
minEvictableIdleTimeMillis: 5000
minIdle: 0
jpa:
show-sql: true
hibernate:
ddl-auto: none
naming_strategy: org.hibernate.cfg.DefaultNamingStrategy
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL5Dialect
hbm2ddl:
auto: none
temp:
use_jdbc_metadata_defaults: false
I am answering here and will close the issue that you have cross-posted
Any "native" property of the JPA implementation (Hibernate) can be set using the spring.jpa.properties prefix as explained here
I haven't looked much further in the actual issue here but to answer this particular question, you can set that hibernate key as follows
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults
Adding this alone worked for me:
spring.jpa.properties.hibernate.dialect: org.hibernate.dialect.Oracle10gDialect
Just replace the last part with your database dialect.
The solution is really useful for me. Thanks
i used file "application.properties" includes following lines:
app.sqlhost=192.168.10.11
app.sqlport=3306
app.sqldatabase=logs
spring.main.web-application-type=none
# Datasource
spring.datasource.url=jdbc:mysql://${app.sqlhost}:${app.sqlport}/${app.sqldatabase}
spring.datasource.username=user
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.hbm2dll.auto = none
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
spring.datasource.continue-on-error=true
spring.datasource.initialization-mode=never
spring.datasource.hikari.connection-timeout=5000
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.initialization-fail-timeout= -1
spring.jpa.hibernate.use-new-id-generator-mappings=true
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
spring.output.ansi.enabled=always
But, you can not use #Transactional annotation at class level
#Service
//#Transactional //do not use to touch the Repository
#EnableAsync
#Scope( proxyMode = ScopedProxyMode.TARGET_CLASS )
public class LogService {
.... }
#Async
#Transactional // you can use at function level
public void deleteLogs(){
logRepository.deleteAllBy ...
}
Add following config should be work:
spring.jpa.database-platform: org.hibernate.dialect.MySQL5Dialect

Grails war deployment on Tomcat asking for hsql driver instead of mysql

I have a grails app that I am trying to deploy onto Tomcat. I used to develop on hsql and wanted to use mysql for production. But when I build the war by running
grails prod war demo.war
and deploy the created war in the tomcat/webapps directory, I get the following error
INFO: Deploying web application archive demo.war
2011-11-29 17:30:03,193 [Thread-2] INFO cfg.Environment - Hibernate 3.3.1.GA
2011-11-29 17:30:03,224 [Thread-2] INFO cfg.Environment - hibernate.properties not found
2011-11-29 17:30:03,240 [Thread-2] INFO cfg.Environment - Bytecode provider name : javassist
2011-11-29 17:30:03,251 [Thread-2] INFO cfg.Environment - using JDK 1.4 java.sql.Timestamp handling
2011-11-29 17:31:25,451 [Thread-2] ERROR context.ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageSource': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Cannot resolve reference to bean 'hibernateProperties' while setting bean property 'hibernateProperties'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateProperties': Cannot resolve reference to bean 'dialectDetector' while setting bean property 'properties' with key [hibernate.dialect]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dialectDetector': Invocation of init method failed; nested exception is org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is org.apache.commons.dbcp.SQLNestedException: Cannot create JDBC driver of class 'org.hsqldb.jdbcDriver' for connect URL 'jdbc:mysql://localhost:3306/demoapp?autoreconnect=true'
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
What's puzzling is that I have removed the hsql dependency completely from the Datasource.groovy file. Here is how my Datasource.groovy looks now.
dataSource {
pooled = true
driver.name = "com.mysql.jdbc.Driver"
username = "root"
password = "root"
}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = true
cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
}
// environment specific settings
environments {
development {
dataSource {
dbCreate = "create-drop" // one of 'create', 'create-drop','update'
pooled = true
driver.name = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://localhost/demoapp_dev?autoreconnect=true"
username = "root"
password = ""
}
}
test {
dataSource {
pooled = true
driver.name = "com.mysql.jdbc.Driver"
dbCreate = "update"
url = "jdbc:mysql://localhost/demoapp_test?autoreconnect=true"
username = "root"
password = ""
}
}
production {
dataSource {
pooled = true
driver.name = "com.mysql.jdbc.Driver"
dbCreate = "update"
url = "jdbc:mysql://localhost/demoapp?autoreconnect=true"
username = "root"
password = ""
}
}
}
How do I get around this problem? Any help is appreciated.
Try using driverClassName instead of driver.name to define your DataSource driver.
This happens when you don't have the MySQL driver in your class path don't have the driverClassName, as per schmolly159's answer.
Make sure mysql-connector-java-x.x.xx.jar is in your lib directory or declare it as a dependency in BuildConfig.groovy.