I am building a Spring 3 MVC app that uses a MySQL database and have recently integrated Flyway into the solution to manage the database migrations. I have successfully conf
The problem is that the identifier public
in the statement is lower case and quoted:
CREATE TABLE "public"...(...)
It should be either unquoted:
CREATE TABLE public...(...)
or uppercase:
CREATE TABLE "PUBLIC"...(...)
The reason why H2 returns the lowercase "public" in the database meta data is that the MySQL mode is used in the database URL (;MODE=MySQL
). So not using the MySQL mode might solve the problem.
Just in case if you want to try liquibase.
I'm using MySQL as my prod environment and h2 as my test environment.
Generate jooq codes with: gradle + liquibase + h2
Found this can solve the problem:
DefaultConfiguration jooqConfiguration = new DefaultConfiguration();
jooqConfiguration.set(new Settings()
// make everything to uppercase
.withRenderNameStyle(RenderNameStyle.UPPER)
// mapping oldSchemaName to newSchemaName
.withRenderMapping(new RenderMapping().withSchemata(
new MappedSchema()
.withInput("input_schema")
.withOutput("OUTPUT_SCHEMA"))
));
Write a profile to apply this in spring for h2. So that mysql configs still fine.
Latest docs here jooq-3.9: settings-name-style.
The schema name in the init script should be quoted or the one you pass to Flyway put in uppercase.
From what I've tested the whole problem occurs only while mixing flyway and H2 with MySql compatibility mode on (doesn't occur if MySql mode is of). It is caused by case sensitivity inconsistency:
In my currently developed application we use MySql as a main database and H2 for testing. My workaround involves creating 'public' (lowercase!) schema during h2 initialization:
spring datasource configuration:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:mem:MY_APP;MODE=MySQL;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1;INIT=RUNSCRIPT FROM 'classpath:db/migration/test/init_tests.sql';"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
init_tests.sql:
CREATE SCHEMA IF NOT EXISTS "public";
Isn't beautifull but works - hope that helps!
From http://www.h2database.com/javadoc/org/h2/engine/DbSettings.html:
databaseToUpper: Database setting DATABASE_TO_UPPER (default: true).
Database short names are converted to uppercase for the DATABASE() function ... Setting this to "false" is experimental. When set to false, all identifier names (table names, column names) are case sensitive...
the problem is that by default schema names are in UPPERCASE.
add ;DATABASE_TO_UPPER=false
to database url
I had a similar issue, although I'm not using Spring. I'm adding H2 in-memory DB for tests on top of an existing setup with jOOQ + Flyway + PostgreSQL.
The solution for me was a combination of changes:
;DATABASE_TO_UPPER=false
to the startup URLCREATE SCHEMA IF NOT EXISTS public;
(I didn't need to use the backticks).SET SCHEMA public;
after schema creation. Note that I wasn't able to add ;SCHEMA=public
to the init URL, because this was throwing an error before the schema was being created. Alternatively:
;DATABASE_TO_UPPER=false;INIT=CREATE SCHEMA IF NOT EXISTS public;
to the startup URL.SET SCHEMA public;
to your init SQL script.