Flyway for Existing PUBLIC schema - java

#Configuration
#ComponentScan("com.sammy")
#EnableTransactionManagement
public class DataSourceConfig {
#Bean(destroyMethod = "shutdown")
public DataSource dataSource(){
EmbeddedDatabaseBuilder databaseBuilder = new EmbeddedDatabaseBuilder();
databaseBuilder.setType(EmbeddedDatabaseType.H2);
databaseBuilder.addScript("classpath:db/migration/V1__Create_Books_Table.sql");
databaseBuilder.addScript("classpath:db/migration/V2__Add_Books.sql");
return databaseBuilder.build();
}
#Bean(name = "entityManagerFactory")
public EntityManagerFactory managerFactory(){
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.hbm2ddl.auto", "create-drop");
jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
LocalContainerEntityManagerFactoryBean managerFactoryBean = new LocalContainerEntityManagerFactoryBean();
managerFactoryBean.setDataSource(dataSource());
managerFactoryBean.setPackagesToScan("com.sammy");
managerFactoryBean.setJpaVendorAdapter(vendorAdapter);
managerFactoryBean.setJpaProperties(jpaProperties);
managerFactoryBean.afterPropertiesSet();
return managerFactoryBean.getObject();
}
#Bean
public PlatformTransactionManager transactionManager(){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(managerFactory());
return transactionManager;
}
}
Above is my data configuration class.
buildscript {
repositories {
jcenter()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "gradle.plugin.com.boxfuse.client:flyway-release:${flywayVersion}"
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:${sonarVersion}"
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
}
}
apply plugin: 'java'
apply plugin: 'jacoco'
apply plugin: 'org.sonarqube'
apply plugin: 'org.flywaydb.flyway'
apply plugin: 'org.springframework.boot'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
jar{
group 'com.sammy'
version '1.0-SNAPSHOT'
}
dependencies {
testCompile "junit:junit:${junitVersion}"
testCompile "info.cukes:cucumber-java:${cucumberVersion}"
testCompile "info.cukes:cucumber-junit:${cucumberVersion}"
//testCompile "info.cukes:cucumber-spring:${cucumberVersion}"
testCompile 'org.springframework.boot:spring-boot-starter-test'
compile 'com.h2database:h2'
compile "org.flywaydb:flyway-core:${flywayVersion}"
compile "org.projectlombok:lombok:${lombokVersion}"
compile("org.springframework.boot:spring-boot-starter-web") {
exclude module: "spring-boot-starter-tomcat"
}
compile 'org.springframework.boot:spring-boot-starter-aop'
compile 'org.springframework.boot:spring-boot-starter-jetty'
compile "io.springfox:springfox-swagger2:${swaggerVersion}"
compile "io.springfox:springfox-swagger-ui:${swaggerVersion}"
compile 'org.springframework.boot:spring-boot-starter-actuator'
compile 'org.springframework.cloud:spring-cloud-starter-config'
compile 'org.springframework.boot:spring-boot-starter-data-jpa'
//compile 'org.springframework.boot:spring-boot-starter-data-mongodb'
}
flyway{
user = 'sa'
schema = ['PUBLIC', 'testdb']
url = 'jdbc:h2:mem:testdb'
baselineVersion = 7.0
baselineOnMigrate = false
baselineDescription = "Base Migration"
}
flywayMigrate{
dependsOn flyway
}
task wrapper(type :Wrapper){
gradleVersion = '3.4.1'
}
I have got that build.gradle file which attempts to configure flyway for use within a SpringBoot application. I'm trying to migrate data to an in-memory H2 database but keep getting the error below:
Exception in thread "main" 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: Found non-empty schema(s) "PUBLIC" without metadata table! Use baseline() or set baselineOnMigrate to true to initialize the metadata table.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
at com.sammy.SpringDataTutorials.main(SpringDataTutorials.java:18)
Caused by: org.flywaydb.core.api.FlywayException: Found non-empty schema(s) "PUBLIC" without metadata table! Use baseline() or set baselineOnMigrate to true to initialize the metadata table.
at org.flywaydb.core.Flyway$1.execute(Flyway.java:954)
at org.flywaydb.core.Flyway$1.execute(Flyway.java:930)
at org.flywaydb.core.Flyway.execute(Flyway.java:1413)
at org.flywaydb.core.Flyway.migrate(Flyway.java:930)
at org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer.afterPropertiesSet(FlywayMigrationInitializer.java:66)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)
... 11 more
I have read some many possible solutions on here but still no joy and even read the official boxfuse website to make sense of what to do but still being able to find a solution. My files are in src/main/resources/db.migration and named as V1__Create_Books_Table.sql and V2__Add_Books.sql. I also see the log message:
[main] DEBUG org.flywaydb.core.internal.command.DbSchemas - Schema "PUBLIC" already exists. Skipping schema creation.
Any help to solve this will be much appreciated. Thanks guys!

I've solved this problem by adding the Spring boot flyway definitions within the application.properties for flyway.baseline-version instead of using the boxfuse gradle plugin.

Related

Springboot external file db configuration

I have application.properties with that code:
spring.config.additional-location=file:///C:/Users/user/Desktop/project/cfg.properties
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=true
and in cfg.properties it looks like that:
spring.datasource.url=jdbc:oracle:thin:#correctDbUrl
spring.datasource.username=user
spring.datasource.password=pass
I think there is something wrong with the path - can't it be outside the project or what happened? This is an error (url is correct, it works when placed directly in application.properties):
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine suitable jdbc url
Gradle:
buildscript {
ext {
springBootVersion = '2.0.3.RELEASE'
}
repositories {
maven { url "someRepository" }
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.abc'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
maven { url "someRepository" }
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
compileOnly('org.projectlombok:lombok')
testCompile('org.springframework.boot:spring-boot-starter-test')
compile(group: 'com.hynnet', name: 'oracle-driver-ojdbc6', version: '12.1.0.1')
compile("org.springframework.boot:spring-boot-starter-data-jpa")
}
Set the following environment variable.
SET SPRING_CONFIG_LOCATION=classpath:/application.properties,file:C:/Users/user/Desktop/project/cfg.properties
you can remove "spring.config.additional-location" from the property file.

Spring: Error creating bean with name 'entityManagerFactory'

I am following the tutorial at https://spring.io/guides/tutorials/bookmarks/ . I used the initializer and decided to use gradle. When attemting to build the application or directly run it, I'm getting the error:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
I guess that's caused by the spring-boot-starter-data-jpa or com.h2database:h2, and probably related to some version mismatch. However, I don't know what to do about it.
My gradle.build:
buildscript {
ext {
springBootVersion = '2.0.0.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-
plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'sfs.examples'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 9.0
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-web')
runtime('com.h2database:h2')
testCompile('org.springframework.boot:spring-boot-starter-test')
}

spring boot data jpa can't connect to mysql database

I try to connect to mysql using spring-boot-starter-data-jpa and hibernate by this example but get
...
2016-07-28 13:20:49.021 ERROR 7765 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name
'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration':
Injection of autowired dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private javax.sql.DataSource
org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource;
nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'dataSource' defined in class path resource
[org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]:
Bean instantiation via factory method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw
exception; nested exception is
org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException:
Cannot determine embedded database driver class for database type
NONE. If you want an embedded database please put a supported one on
the classpath. If you have database settings to be loaded from a
particular profile you may need to active it (no profiles are
currently active)
...
application.properties:
# DataSource settings: set here your own configurations for the database
# connection. In this example we have "netgloo_blog" as database name and
# "root" as username and password.
spring.datasource.url = jdbc:mysql://localhost:3306/db
spring.datasource.username = db
spring.datasource.password = pass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# Keep the connection alive if idle for a long time (needed in production)
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# Use spring.jpa.properties.* for Hibernate native properties (the prefix is
# stripped before adding them to the entity manager)
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
project structure in eclipse:
build.gradle :
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle- plugin:1.3.6.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'
jar {
baseName = 'gs-accessing-data-jpa'
version = '0.1.0'
}
repositories {
mavenCentral()
maven { url "https://repository.jboss.org/nexus/content/repositories/releases" }
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.3.6.RELEASE'
compile group: 'mysql', name: 'mysql-connector-java', version: '6.0.3'
//also tried
runtime group: 'mysql', name: 'mysql-connector-java', version: '6.0.3'
runtime "org.apache.tomcat:tomcat-jdbc:7.0.47"
testCompile("junit:junit")
}
task wrapper(type: Wrapper) {
gradleVersion = '2.3'
}
You did not add the driver class
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
<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>
</dependency>
Check for these dependencies as well
Can you add runtime dependency in gradle as opposed to compile time dependency on the MYSQL Driver jar ?
dependencies {
//compile "mysql:mysql-connector-java:6.0.3"
runtime "mysql:mysql-connector-java:6.0.3"
runtime "org.apache.tomcat:tomcat-jdbc:7.0.47"
}
do you have database driver on the classpath?
have you set property spring.datasource.driver-class-name?
For more details, see
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html

Spring configuration: Unable to locate Spring NamespaceHandler

Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/tx] Offending resource: ServletContext resource [/WEB-INF/spring-servlet.xml]
In gradle you can use shadowJar plugin for fix that. My build.gradle file for compile fat jar:
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'application'
mainClassName = 'ru.antowka.Initializer'
buildscript {
repositories { jcenter() }
dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.2'
}
}
jar {
manifest {
attributes 'Main-Class': mainClassName
}
}
shadowJar {
mergeServiceFiles('META-INF/spring.*')
}
// JDK 8
sourceCompatibility = 1.8
targetCompatibility = 1.8
compileJava.options.encoding = 'UTF-8'
repositories {
maven {
url 'http://repo.spring.io/snapshot'
}
mavenLocal()
mavenCentral()
jcenter()
}
dependencies {
compile 'org.jsoup:jsoup:1.8.3'
compile 'org.springframework:spring-context:4.2.2.BUILD-SNAPSHOT'
compile 'log4j:log4j:1.2.17'
compile 'org.quartz-scheduler:quartz:1.8.6'
compile 'org.springframework:spring-support:2.0.8'
compile 'org.springframework:spring-tx:2.5.4'
compile 'org.springframework:spring-orm:4.1.7.RELEASE'
compile 'org.hibernate:hibernate-core:4.3.10.Final'
compile 'org.postgresql:postgresql:9.4-1201-jdbc41'
compile 'org.apache.commons:commons-dbcp2:2.1'
testCompile 'org.springframework:spring-test:4.2.0.RELEASE'
testCompile 'org.mockito:mockito-core:1.+'
testCompile 'junit:junit:4.12'
}

Spring boot : access rest api from #Scheduled method

I try below guild of schedule-task and it worked.
http://spring.io/guides/gs/scheduling-tasks/
next, I want to access web-api from #Scheduled annotated method, and add below dependency to my build.gradle, to use RestTemplate.
compile 'org.springframework.boot:spring-boot-starter-web:1.2.1.RELEASE'
but, below Exception occurs.
Exception in thread "main" org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:133)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:474)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:961)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:950)
at my.pkg.Application.main(BatchApplication.java:14)
Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:183)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:156)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130)
do I need specific setting to use RestTemplate from #Scheduled method ?
my full build.gradle is below, other files are same to guide.
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.2.1.RELEASE'
}
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'spring-boot'
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter:1.2.1.RELEASE'
// below line I added.
compile 'org.springframework.boot:spring-boot-starter-web:1.2.1.RELEASE'
}
A dependency on spring-boot-starter-web is intended for web applications that need a servlet container. It's overkill if all you need is RestTemplate. Replace the dependency with one on org.springframework:spring-web

Categories

Resources