How to handle UTF-8 charset with Oracle using FlywayDB - java

Here is flyway maven plugin configuration:
<plugins>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<sqlMigrationSuffix>.oracle.sql</sqlMigrationSuffix>
<placeholderReplacement>true</placeholderReplacement>
<placeholderPrefix>#[</placeholderPrefix>
<placeholderSuffix>]</placeholderSuffix>
<encoding>UTF-8</encoding>
<table>T00M001</table>
<locations>
<location>classpath:/META-INF/flyway/oracle</location>
<location>classpath:/com/chorke/dbms/jdbcmi/oracle</location>
</locations>
<resolvers>
<resolver>com.chorke.dbms.flyway.resolvers.FlywayResolverImpl</resolver>
</resolvers>
<callbacks>
<callback>com.chorke.dbms.flyway.callbacks.AfterEachMigrate</callback>
<callback>com.chorke.dbms.flyway.callbacks.BeforeEachMigrate</callback>
</callbacks>
<serverId>chorke.flyway.oracle</serverId>
<url>jdbc:oracle:thin:#127.0.0.1:1521:xe</url>
</configuration>
<dependencies>
<dependency>
<groupId>com.chorke.dbms</groupId>
<artifactId>chorke-dbms-flyway</artifactId>
<version>1.0.00-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.chorke.dbms</groupId>
<artifactId>chorke-dbms-oracle</artifactId>
<version>1.0.00-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.chorke.dbms</groupId>
<artifactId>chorke-dbms-jdbcmi</artifactId>
<version>1.0.00-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
</dependencies>
</plugin>
</plugins>
Here is flyway.properties
flyway.encoding: UTF-8
flyway.placeholders.key: value
flyway.placeholders.name: nome
flyway.placeholders.prop: value
Here is the snippet of migration script:
-- DDL OF T01I001
-- -----------------------------------------------------------------------------
CREATE TABLE t01i001
(
t_msg_code VARCHAR2(5 BYTE) NOT NULL
, t_lang1_msg VARCHAR2(80 BYTE)
, t_lang2_msg VARCHAR2(80 BYTE)
, t_entry_user VARCHAR2(4 BYTE)
, t_entry_date DATE
, t_upd_user VARCHAR2(4 BYTE)
, t_upd_date DATE
);
-- DML OF T01I001
-- -----------------------------------------------------------------------------
INSERT INTO t01i001 (t_msg_code,t_lang1_msg,t_lang2_msg,t_entry_user
,t_entry_date,t_upd_user,t_upd_date) VALUES ('00','يوجد سجل أخر لليوم والوقت المحدد'
,'Record already exists for the specified Date and Time.','2'
,to_date('13-10-2005','DD-MM-YYYY'),'C',to_date('27-11-2005','DD-MM-YYYY'));
INSERT INTO t01i001 (t_msg_code,t_lang1_msg,t_lang2_msg,t_entry_user
,t_entry_date,t_upd_user,t_upd_date) VALUES ('01'
,'البيانات قد أدخلت من قبل لرقم الزيارة هذا'
,'Data has already been entered for this Visit Number.','2'
,to_date('13-10-2005','DD-MM-YYYY'),'C',to_date('27-11-2005','DD-MM-YYYY'));
Here is the registry for charset of oracle 11g XE R2:
NLS_LANG =AMERICAN_AMERICA.UTF8
Here is the maven goals:
mvn clean install flyway:migrate flyway:info
There is two type of problem occurred:
t_lang1_msg size exceed
imported character changed
While we increased t_lang1_msg size than migration work fine. but it is automatically converted يوجد سجل أخر لليوم والوقت المحدد to يوجد سجل أخر لليوم والوقت المحدد. Which one unreadable to us.
Any solution regarding to the issue? We appreciate your answer to resolving this issue.

Actually there was no doubt about the configuration of flyway-maven-plugin, flyway.properties as well as sql script and it's encoding. But there was an problem inside ant script target. Where there was an task to concat sql files in specific order for per sprint basis. that's as following:
<concat destfile="${file.flyway.sql.concat}" outputencoding="UTF-8"append="true">
<sort xmlns:rcmp="antlib:org.apache.tools.ant.types.resources.comparators">
<fileset refid="dir.set.flyway.db.version.build"/>
<rcmp:name />
</sort>
</concat>
After adding encoding="UTF-8" attribute to concat task it is working fine.
<concat destfile="${file.flyway.sql.concat}"
outputencoding="UTF-8" encoding="UTF-8" append="true">
<sort xmlns:rcmp="antlib:org.apache.tools.ant.types.resources.comparators">
<fileset refid="dir.set.flyway.db.version.build"/>
<rcmp:name />
</sort>
</concat>
That's resolve this issue.

Related

Flyway is unable to create and find database in Spring Boot [duplicate]

Question: Is it possible to create a new DB in a migration script and then connect to it? How?
My Scenario:
I'm trying to use flyway in my Java project (RESTful application using Jersey2.4 + tomcat 7 + PostgreSQL 9.3.1 + EclipseLink) for managing the changes between different developers which are using git. I wrote my init script and ran it with:
PGPASSWORD='123456' psql -U postgres -f migration/V1__initDB.sql
and it worked fine. The problem is that I can't create new DB with my scripts. when I include the following line in my script:
CREATE DATABASE my_database OWNER postgres ENCODING 'UTF8';
I get this error:
org.postgresql.util.PSQLException: ERROR: CREATE DATABASE cannot run inside a transaction block
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2157)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1886)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:555)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:403)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:395)
at com.googlecode.flyway.core.dbsupport.JdbcTemplate.executeStatement(JdbcTemplate.java:230)
at com.googlecode.flyway.core.dbsupport.SqlScript.execute(SqlScript.java:89)
at com.googlecode.flyway.core.resolver.sql.SqlMigrationExecutor.execute(SqlMigrationExecutor.java:72)
at com.googlecode.flyway.core.command.DbMigrate$2.doInTransaction(DbMigrate.java:252)
at com.googlecode.flyway.core.command.DbMigrate$2.doInTransaction(DbMigrate.java:250)
at com.googlecode.flyway.core.util.jdbc.TransactionTemplate.execute(TransactionTemplate.java:56)
at com.googlecode.flyway.core.command.DbMigrate.applyMigration(DbMigrate.java:250)
at com.googlecode.flyway.core.command.DbMigrate.access$700(DbMigrate.java:47)
at com.googlecode.flyway.core.command.DbMigrate$1.doInTransaction(DbMigrate.java:189)
at com.googlecode.flyway.core.command.DbMigrate$1.doInTransaction(DbMigrate.java:138)
at com.googlecode.flyway.core.util.jdbc.TransactionTemplate.execute(TransactionTemplate.java:56)
at com.googlecode.flyway.core.command.DbMigrate.migrate(DbMigrate.java:137)
at com.googlecode.flyway.core.Flyway$1.execute(Flyway.java:872)
at com.googlecode.flyway.core.Flyway$1.execute(Flyway.java:819)
at com.googlecode.flyway.core.Flyway.execute(Flyway.java:1200)
at com.googlecode.flyway.core.Flyway.migrate(Flyway.java:819)
at ir.chom.MyApp.<init>(MyApp.java:28)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.glassfish.hk2.utilities.reflection.ReflectionHelper.makeMe(ReflectionHelper.java:1117)
at org.jvnet.hk2.internal.Utilities.justCreate(Utilities.java:867)
at org.jvnet.hk2.internal.ServiceLocatorImpl.create(ServiceLocatorImpl.java:814)
at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:906)
at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:898)
at org.glassfish.jersey.server.ApplicationHandler.createApplication(ApplicationHandler.java:300)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:279)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:302)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:167)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:349)
at javax.servlet.GenericServlet.init(GenericServlet.java:160)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1280)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1091)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5176)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5460)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3954)
at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:426)
at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1345)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1530)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1519)
at java.lang.Thread.run(Thread.java:724)
It seems that this is a problem with JDBC that uses autocommit option. This option can be disabled with something like this:
Connection connection = dataSource.getConnection();
Connection.setAutoCommit(false); // Disables auto-commit.
but I don't know how to pass this option to flyway connection. Also if I solve this I think I will have problem with passing password to \c command.
Flyway always operates within the database used in the jdbc connection string.
Once connected, all scripts run within a transaction. As CREATE DATABASE is not supported within transactions, you will not be able to accomplish what you want.
What you can do however, is create a schema instead. Flyway will even do this for you, if you point it at a non-existing one.
I dont know if this is even possible to do in flyway.
Flyway is intended to connect to an already existing database (whether it is empty or not). It also would be a good practice to keep your database creation separate from your database migrations.
Here is a workaround that worked for me (assuming the use of the Maven plugin):
Configure the plugin with two executions. The first execution creates the database. The second execution migrates an existing database.
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>${flyway.version}</version>
<executions>
<execution>
<id>create-db</id>
<goals>
<goal>migrate</goal>
</goals>
<configuration>
<driver>org.postgresql.Driver</driver>
<url>jdbc:postgresql://database-server/</url>
<user>postgres</user>
<password>password</password>
<placeholders>
<DATABASE.NAME>MyDatabase</DATABASE.NAME>
</placeholders>
<locations>
<location>com/foo/bar/database/create</location>
</locations>
</configuration>
</execution>
<execution>
<id>migrate-db</id>
<goals>
<goal>migrate</goal>
</goals>
<configuration>
<driver>org.postgresql.Driver</driver>
<url>jdbc:postgresql://database-server/MyDatabase</url>
<user>postgres</user>
<password>password</password>
<locations>
<location>com/foo/bar/database/migrate</location>
</locations>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency>
</dependencies>
</plugin>
Then add V1__Created_database.sql to the com/foo/bar/database/create directory. This file contains:
CREATE DATABASE ${DATABASE.NAME}
Flyway can't create database for you.
It can create schema if you didn't create one by
flyway.schemas: schema1,schema2
You can try what is suggested in this issue: https://github.com/flyway/flyway/issues/2556, use the createDatabaseIfNotExist parameter in the mysql url configured in flyway, as below:
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>6.4.1</version>
<configuration>
<url>jdbc:mysql://localhost:3306/<databaseName>?createDatabaseIfNotExist=true</url>
<user>root</user>
<password>root</password>
</configuration>
If u have schema database creation command in V1 of your scripts, flyway can generate it but not database:
flyway -baselineOnMigrate=true -url=jdbc:mysql://localhost/ -schemas=test_db -user=root -password=root_pass -locations=filesystem:/path/to/scrips/ migrate
and similar to this in the script file:
DROP SCHEMA IF EXISTS `test_db` ;
CREATE SCHEMA `test_db` COLLATE utf8_general_ci ;

Openapi generator cannot generate query param with enum

I'm trying to generate a service that has enum as query parameter, but it keeps generating it wrong.
Here's the part of yaml:
name: language
in: query
description: language
schema:
type: string
enum:
- en
- de
and I'm using it in parameters:
- $ref: '#/components/parameters/language'
The error that I get is:
[ERROR] .../api/TestApi.java:[110,65] illegal start of type
[ERROR] .../api/TestApi.java:[110,66] ')' expected
[ERROR] .../api/TestApi.java:[110,82] ';' expected
Here's what the code looks like:
public Response getByLanguage( #PathParam("id") Long id, , allowableValues="en, de" #QueryParam("language") String language
And here's my plugin:
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>5.0.1</version>
<configuration>
<inputSpec>${basedir}/src/main/resources/openapi.yaml</inputSpec>
<output>${project.build.directory}/generated-sources/java</output>
<generatorName>jaxrs-resteasy-eap</generatorName>
<modelPackage>com.openapi.example.model</modelPackage>
<apiPackage>com.openapi.example.api</apiPackage>
<generateSupportingFiles>false</generateSupportingFiles>
<configOptions>
<sourceFolder>openapi</sourceFolder>
<dateLibrary>java8</dateLibrary>
<interfaceOnly>true</interfaceOnly>
<java8>true</java8>
<serializableModel>true</serializableModel>
<useTags>true</useTags>
<performBeanValidation>true</performBeanValidation>
<useBeanValidation>true</useBeanValidation>
</configOptions>
</configuration>
<executions>
<execution>
<phase>generate-resources</phase>
<id>generate</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
The only way I've managed to get it to work is to make it as an array of enum values, but that's not what I need here.
EDIT:
dependencies I have defined in the project:
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-dependency-analyzer</artifactId>
<version>1.11.1</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<version>1.5.8</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.1.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.11.3</version>
</dependency>
Multiple long standing enum bugs exist in the generators (for all languages as far as I can tell).
For example https://github.com/OpenAPITools/openapi-generator/issues/4300
But also .. https://github.com/OpenAPITools/openapi-generator/issues/2645
Try out with below demo yaml.
Enums should be defined as enum: [en, de].
openapi: 3.0.2
info: {title: Demo Info., description: Demo Description., version: 1.0.0}
servers:
- {url: 'https://something.com', description: Demo Description.}
paths:
/something:
post:
tags: [Something]
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/SomethingRequest'}
parameters:
- {$ref: '#/components/parameters/language'}
responses:
200:
description: OK
content:
application/json:
schema: {$ref: '#/components/schemas/SomethingResponse'}
components:
parameters:
language:
name: language
schema:
type: string
enum: [en, de]
default: en
in: query
schemas:
SomethingRequest:
properties:
demo: {type: string}
SomethingResponse:
properties:
demo: {type: string}
It depends what generator you are using but jaxrs-resteasy-eap is broken when using enums in query parameters.
I think this commit is causing the problem.
As a temporary fix in my project I edited the queryParams.mustache template file to as this:
{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{^isContainer}}{{#allowableValues}}#ApiParam(value = "{{{description}}}"{{#required}},required=true{{/required}}, {{> allowableValues }}){{/allowableValues}}{{#defaultValue}} #DefaultValue("{{{.}}}"){{/defaultValue}}{{/isContainer}} #QueryParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/isQueryParam}}
Just noticed that there are also github issue of this. The recommendation of removing the allowableValues from queryParams.mustache might be the correct way to go:
{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{^isContainer}}{{#defaultValue}} #DefaultValue("{{{.}}}"){{/defaultValue}}{{/isContainer}} #QueryParam("{{baseName}}") {{{dataType}}} {{paramName}}{{/isQueryParam}}
It depends how you are using the generator how to use own templates.
I am using it from npm #openapitools/openapi-generator-cli
There you can apply your own templates by adding -t/--template-dir option into your generate command. Here is mine as example:
npx #openapitools/openapi-generator-cli generate -t=templates/jaxrs -i openapi.yaml -o generated/jaxrs -g jaxrs-resteasy-eap -c config-jaxrs.yaml
I just copied my modified queryParams.mustache to root of templates/jaxrs and the generated api functions did not have double comma syntax problems anymore:
public Response getPets( #ApiParam(value = "My param description", allowableValues="AA, BB, CC") #QueryParam("petType") PetType petType,#Context SecurityContext securityContext);
I haven't used these files yet, so I don't know if everything is correct, but atleast the syntax is correct now.
More info here: templating documentation

How to create a database with flyway?

Question: Is it possible to create a new DB in a migration script and then connect to it? How?
My Scenario:
I'm trying to use flyway in my Java project (RESTful application using Jersey2.4 + tomcat 7 + PostgreSQL 9.3.1 + EclipseLink) for managing the changes between different developers which are using git. I wrote my init script and ran it with:
PGPASSWORD='123456' psql -U postgres -f migration/V1__initDB.sql
and it worked fine. The problem is that I can't create new DB with my scripts. when I include the following line in my script:
CREATE DATABASE my_database OWNER postgres ENCODING 'UTF8';
I get this error:
org.postgresql.util.PSQLException: ERROR: CREATE DATABASE cannot run inside a transaction block
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2157)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1886)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:555)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:403)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:395)
at com.googlecode.flyway.core.dbsupport.JdbcTemplate.executeStatement(JdbcTemplate.java:230)
at com.googlecode.flyway.core.dbsupport.SqlScript.execute(SqlScript.java:89)
at com.googlecode.flyway.core.resolver.sql.SqlMigrationExecutor.execute(SqlMigrationExecutor.java:72)
at com.googlecode.flyway.core.command.DbMigrate$2.doInTransaction(DbMigrate.java:252)
at com.googlecode.flyway.core.command.DbMigrate$2.doInTransaction(DbMigrate.java:250)
at com.googlecode.flyway.core.util.jdbc.TransactionTemplate.execute(TransactionTemplate.java:56)
at com.googlecode.flyway.core.command.DbMigrate.applyMigration(DbMigrate.java:250)
at com.googlecode.flyway.core.command.DbMigrate.access$700(DbMigrate.java:47)
at com.googlecode.flyway.core.command.DbMigrate$1.doInTransaction(DbMigrate.java:189)
at com.googlecode.flyway.core.command.DbMigrate$1.doInTransaction(DbMigrate.java:138)
at com.googlecode.flyway.core.util.jdbc.TransactionTemplate.execute(TransactionTemplate.java:56)
at com.googlecode.flyway.core.command.DbMigrate.migrate(DbMigrate.java:137)
at com.googlecode.flyway.core.Flyway$1.execute(Flyway.java:872)
at com.googlecode.flyway.core.Flyway$1.execute(Flyway.java:819)
at com.googlecode.flyway.core.Flyway.execute(Flyway.java:1200)
at com.googlecode.flyway.core.Flyway.migrate(Flyway.java:819)
at ir.chom.MyApp.<init>(MyApp.java:28)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.glassfish.hk2.utilities.reflection.ReflectionHelper.makeMe(ReflectionHelper.java:1117)
at org.jvnet.hk2.internal.Utilities.justCreate(Utilities.java:867)
at org.jvnet.hk2.internal.ServiceLocatorImpl.create(ServiceLocatorImpl.java:814)
at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:906)
at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:898)
at org.glassfish.jersey.server.ApplicationHandler.createApplication(ApplicationHandler.java:300)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:279)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:302)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:167)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:349)
at javax.servlet.GenericServlet.init(GenericServlet.java:160)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1280)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1091)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5176)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5460)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3954)
at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:426)
at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1345)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1530)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1519)
at java.lang.Thread.run(Thread.java:724)
It seems that this is a problem with JDBC that uses autocommit option. This option can be disabled with something like this:
Connection connection = dataSource.getConnection();
Connection.setAutoCommit(false); // Disables auto-commit.
but I don't know how to pass this option to flyway connection. Also if I solve this I think I will have problem with passing password to \c command.
Flyway always operates within the database used in the jdbc connection string.
Once connected, all scripts run within a transaction. As CREATE DATABASE is not supported within transactions, you will not be able to accomplish what you want.
What you can do however, is create a schema instead. Flyway will even do this for you, if you point it at a non-existing one.
I dont know if this is even possible to do in flyway.
Flyway is intended to connect to an already existing database (whether it is empty or not). It also would be a good practice to keep your database creation separate from your database migrations.
Here is a workaround that worked for me (assuming the use of the Maven plugin):
Configure the plugin with two executions. The first execution creates the database. The second execution migrates an existing database.
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>${flyway.version}</version>
<executions>
<execution>
<id>create-db</id>
<goals>
<goal>migrate</goal>
</goals>
<configuration>
<driver>org.postgresql.Driver</driver>
<url>jdbc:postgresql://database-server/</url>
<user>postgres</user>
<password>password</password>
<placeholders>
<DATABASE.NAME>MyDatabase</DATABASE.NAME>
</placeholders>
<locations>
<location>com/foo/bar/database/create</location>
</locations>
</configuration>
</execution>
<execution>
<id>migrate-db</id>
<goals>
<goal>migrate</goal>
</goals>
<configuration>
<driver>org.postgresql.Driver</driver>
<url>jdbc:postgresql://database-server/MyDatabase</url>
<user>postgres</user>
<password>password</password>
<locations>
<location>com/foo/bar/database/migrate</location>
</locations>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency>
</dependencies>
</plugin>
Then add V1__Created_database.sql to the com/foo/bar/database/create directory. This file contains:
CREATE DATABASE ${DATABASE.NAME}
Flyway can't create database for you.
It can create schema if you didn't create one by
flyway.schemas: schema1,schema2
You can try what is suggested in this issue: https://github.com/flyway/flyway/issues/2556, use the createDatabaseIfNotExist parameter in the mysql url configured in flyway, as below:
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>6.4.1</version>
<configuration>
<url>jdbc:mysql://localhost:3306/<databaseName>?createDatabaseIfNotExist=true</url>
<user>root</user>
<password>root</password>
</configuration>
If u have schema database creation command in V1 of your scripts, flyway can generate it but not database:
flyway -baselineOnMigrate=true -url=jdbc:mysql://localhost/ -schemas=test_db -user=root -password=root_pass -locations=filesystem:/path/to/scrips/ migrate
and similar to this in the script file:
DROP SCHEMA IF EXISTS `test_db` ;
CREATE SCHEMA `test_db` COLLATE utf8_general_ci ;

Oracle with Spring roo

I've been try to get spring roo generating entities from an oracle database.
However I kept getting the error JDBC driver not available for oracle.jdbc.OracleDriver
I've installed my ojdbc14.jar to my local maven respository
mvn install:install-file -Dfile=ojdbc14.jar -DgroupId=com.oracle -DartifactId=ojdbc14 -Dversion=10.2.0.2 -Dpackaging=jar -DgeneratePom=true
I've check my pom.xml and it points to the correct version and when I mvn clean install it compiles correctly.
I'm not sure what I'm missing. I've had it work using MySql but no job with Oracle.
What am I doing wrong ?
Roo version 1.2.2.RELEASE
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.2</version>
<classifier />
</dependency>
....
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.2</version>
</dependency>
#Updated at Tue Nov 13 22:43:01 NZDT 2012
#Tue Nov 13 22:43:01 NZDT 2012
database.driverClassName=oracle.jdbc.OracleDriver
database.url=jdbc\:oracle\:thin\:#[server.ip]\:1521\:orcl
database.username=MYUSER
database.password=MYPASSWORD
Where [server.ip] is the databases ip address
Hi,
I didn't do anything with OSGI.
After downloading the jar you mentioned. (Downloaded it from here http://www.java2s.com/Code/Jar/b/DownloadbizaQutebndjar.htm)
I ran the command you gave me but it produced an error.
oracle/sql/converter_xcharset
lx20001.glb
lx20002.glb
lx2001f.glb
lx200b2.glb
One error
1 : Unresolved references to [javax.naming, javax.naming.directory, javax.naming.spi, javax.net, javax.net.ssl, javax.resource, javax.resource.spi, javax.resource.spi.endpoint, javax.resource.spi.security, javax.security.auth, javax.security.cert, javax.sql, javax.sql.rowset, javax.sql.rowset.spi, javax.transaction.xa, javax.xml.parsers, oracle.i18n.text.converter, oracle.ons, oracle.security.pki, org.w3c.dom, org.xml.sax, org.xml.sax.helpers] by class(es) on the Bundle-Classpath[Jar:ojdbc14.jar]: [oracle/jdbc/pool/OracleConnectionCacheManager$1.class, oracle/jdbc/rowset/OracleCachedRowSetReader.class, oracle/jdbc/pool/OracleRuntimeLoadBalancingEventHandlerThread$1.class, oracle/jdbc/rowset/OracleWebRowSet.class, oracle/jdbc/internal/OracleConnection.class, oracle/jdbc/connector/OracleManagedConnectionMetaData.class, oracle/jdbc/xa/OracleXAConnection.class, oracle/jdbc/xa/OracleXAException.class, oracle/jdbc/xa/OracleXADataSource.class, oracle/jdbc/pool/OracleOCIConnectionPool.class, oracle/jdbc/connector/OracleConnectionManager.class, oracle/jdbc/rowset/OracleJDBCRowSet.class, oracle/net/nt/TcpsConfigure.class, oracle/jdbc/rowset/OraclePredicate.class, oracle/jdbc/pool/OracleRuntimeLoadBalancingEventHandlerThread.class, oracle/jdbc/connector/OracleResourceAdapter.class, oracle/jdbc/pool/OracleConnectionCacheTimeOutThread.class, oracle/net/jndi/CustomSSLSocketFactory.class, oracle/jdbc/rowset/OracleRowSetMetaData.class, oracle/jdbc/driver/T4CXAResource.class, oracle/jdbc/rowset/OracleFilteredRowSet.class, oracle/jdbc/xa/OracleXid.class, oracle/jdbc/rowset/OracleWebRowSetXmlWriter.class, oracle/jdbc/rowset/OracleJoinable.class, oracle/jdbc/pool/OracleConnectionCacheImpl.class, oracle/jdbc/connector/OracleManagedConnectionFactory.class, oracle/jdbc/pool/OracleFailoverEventHandlerThread$1.class, oracle/sql/converter/CharacterConverterFactoryOGS.class, oracle/jdbc/pool/OracleConnectionEventListener.class, oracle/jdbc/rowset/OracleWebRowSetXmlReaderImpl.class, oracle/jdbc/pool/OracleXAConnectionCacheImpl.class, oracle/jdbc/rowset/OracleWebRowSetXmlWriterImpl.class, oracle/jdbc/driver/PhysicalConnection.class, oracle/jdbc/xa/client/OracleXADataSource.class, oracle/net/jndi/TrustManagerSSLSocketFactory.class, oracle/jdbc/xa/client/OracleXAResource.class, oracle/jdbc/xa/OracleXAResource.class, oracle/jdbc/pool/OracleConnectionCacheEventListener.class, oracle/jdbc/rowset/OracleRowSetListenerAdapter.class, oracle/jdbc/rowset/OracleWebRowSetXmlReaderDomHandler.class, oracle/jdbc/connector/OracleConnectionRequestInfo.class, oracle/jdbc/pool/OracleDataSourceFactory.class, oracle/net/jndi/JndiAttrs.class, oracle/jdbc/rowset/OracleJoinRowSet.class, oracle/jdbc/rowset/OracleWebRowSetXmlReader.class, oracle/jdbc/xa/client/OracleXAHeteroConnection.class, oracle/jdbc/driver/T4CXAConnection.class, oracle/net/nt/CustomSSLSocketFactory.class, oracle/net/nt/TcpsNTAdapter.class, oracle/jdbc/rowset/OracleCachedRowSetWriter.class, oracle/jdbc/rowset/OracleCachedRowSet.class, oracle/jdbc/pool/OraclePooledConnection.class, oracle/jdbc/pool/OracleFailoverEventHandlerThread.class, oracle/jdbc/xa/client/OracleXAConnection.class, oracle/jdbc/pool/OracleConnectionPoolDataSource.class, oracle/jdbc/driver/LogicalConnection.class, oracle/jdbc/pool/OracleConnectionCacheManager.class, oracle/jdbc/rowset/OracleRowSet.class, oracle/jdbc/pool/OracleImplicitConnectionCache.class, oracle/jdbc/connector/OracleManagedConnection.class, oracle/jdbc/pool/OracleConnectionCache.class, oracle/jdbc/xa/client/OracleXAHeteroResource.class, oracle/jdbc/driver/OracleDriver.class, oracle/jdbc/rowset/OracleWebRowSetXmlReaderContHandler.class, oracle/jdbc/connector/OracleLocalTransaction.class, oracle/net/jndi/TrustManager.class, oracle/jdbc/pool/OracleDataSource.class]
So I didn't get the expected result.
Any idea on this ?
Thanks for the help.
Did you create an Oracle JDBC driver (ojdbc) for OSGI? From Roo docs:
currently there are no open-source JDBC drivers for Oracle or DB2 and
Roo does not provide OSGi drivers for these databases.
You can follow instructions in the given docs. Otherwise, the biz.aQute.bnd.jar helps you to create an OSGi bundle version of the OJDBC driver.
To do that download this zip file and unzip it. Then in the same folder put your ojdbc14.jar and run the command:
java -jar biz.aQute.bnd.jar wrap ojdbc14.jar
I get one warning (Superfluous export-package instructions: [oracle.net, oracle, oracle.jpub, oracle.security, oracle.core]) which I ignore.
As a result of this step you should get a new file: ojdbc14.bar
Rename it whatever you want but with .jar extension. e.g. 'ojdbc14-osgi.jar'
Install the jar in roo with
roo> osgi start --url file:///tmp/ojdbc14-osgi.jar
roo> database reverse engineer ... and so on
Just one thing to note. Remember to edit the version of the ojdbc14 artifactId in the Roo generated pom.xml if necessary.
Hope it helps. I have done it with 3 projects and 3 databases without problems.
If you are getting the error during running with mvn jetty:run, or mvn tomcat:run you can try adding the dependency to the tomcat and jetty config:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<httpsPort>9443</httpsPort>
</configuration>
<dependencies>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.2</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.4.v20120524</version>
<configuration>
<webAppConfig>
<contextPath>/${project.name}</contextPath>
</webAppConfig>
</configuration>
<dependencies>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.2</version>
</dependency>
</dependencies>
</plugin>

org.hibernate.hql.ast.QuerySyntaxException with Hibernate

I'm new to using Hibernate with Java. I'm getting the following exception. The stuff that I found online regarding this error didn't seem to help. Any ideas? The Exception:
java.lang.IllegalArgumentException: org.hibernate.hql.ast.QuerySyntaxException:
ApplPerfStats is not mapped [select count(c) from ApplPerfStats c]
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:601)
at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:96)
at com.icesoft.icefaces.samples.datatable.jpa.CustomerDAO.findTotalNumberCustomers(CustomerDAO.java:89)
at com.icesoft.icefaces.samples.datatable.ui.SessionBean.getDataPage(SessionBean.java:189)
at com.icesoft.icefaces.samples.datatable.ui.SessionBean.access$0(SessionBean.java:185)
at com.icesoft.icefaces.samples.datatable.ui.SessionBean$LocalDataModel.fetchPage(SessionBean.java:245)
at com.icesoft.icefaces.samples.datatable.ui.PagedListDataModel.getPage(PagedListDataModel.java:121)
at com.icesoft.icefaces.samples.datatable.ui.PagedListDataModel.getRowCount(PagedListDataModel.java:100)
at com.icesoft.faces.component.datapaginator.DataPaginator.isModelResultSet(DataPaginator.java:1091)
at com.icesoft.faces.component.datapaginator.DataPaginatorRenderer.encodeBegin(DataPaginatorRenderer.java:201)
The place where this is called:
#SuppressWarnings("unchecked")
public Long findTotalNumberCustomers() {
EntityManagerHelper.log("finding number of Customer instances", Level.INFO, null);
try {
String queryString = "select count(c) from ApplPerfStats c";
return (Long) getEntityManager().createQuery(queryString).getSingleResult();
} catch (RuntimeException re) {
EntityManagerHelper.log("find number of Appl_perf_stats failed",
Level.SEVERE, re);
throw re;
}
}
The class that maps to the database table:
package com.icesoft.icefaces.samples.datatable.jpa;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "Appl_perf_stats", uniqueConstraints = {})
public class ApplPerfStats implements java.io.Serializable {
.....
Thanks,
Tam
Try adding a class element under persistence-unit, in your persistence.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<persistence ...>
<persistence-unit name="unit">
<class>com.icesoft.icefaces.samples.datatable.jpa.ApplPerfStats</class>
...
</persistence-unit>
<persistence>
I haven't done much more than that with JPA/EntityManager, so I don't know if there's a way to add an entire package. AFAIK, when using hibernate.cfg.xml, each persistent class has to be specified directly.
It happened to me until I started to use the full class name, e.g.:
String queryString = "select count(c) from com.my.classes.package.ApplPerfStats c";
But I don't like this approach, because it's refactoring-unfirendly. A more tractable one would be:
String queryString = "select count(c) from " + ApplPerfStats.class.getName() + c";
javashlook's solution seems to be a shortcut for that - but it adds more XML configuration, which I try to avoid. If only there was an annotation-based way to specify that...
I was having the same problem and I solved by adding aspectj entries to my pom.xml see below. I guess it makes sense if you are using annotations. Otherwise you need to specify the mappings in the XML file. I had this problem from a project that was using a jar with JPA annotations.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.2</version> <!-- NB: do use 1.3 or 1.3.x due to MASPECTJ-90 - wait for 1.4 -->
<dependencies>
<!-- NB: You must use Maven 2.0.9 or above or these are ignored (see MNG-2972) -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<configuration>
<weaveDependencies>
<weaveDependency> <groupId>your.project</groupId> <artifactId>your.artifact</artifactId> </weaveDependency>
</weaveDependencies>
</configuration>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<outxml>true</outxml>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
You should specify a column to do the count on
select count(c.someColumn) from ApplPerfStats c
Or try a count(*)
select count(*) from ApplPerfStats c
I faced this issue but in my case the problem was due to gradle version.
When I changed my system from linux to mac then I had to switch from gradle-1.0-milestone-3 to gradle-1.0-milestone-4 as milestone-3 does not work in OSX. And in gradle-1.0-milestone-4 I faced the same issue then I had to degrade my gradle version to gradle-1.0-milestone-1. Now it is working fine
I was also face this problem fixed by this ...
You haven't declared your entity classes in persistence.xml config file:
<property name="hibernate.archive.autodetection" value="class, hbm"/>
I know it has been a long time on this matter, but none of the above answers solved my problem.
I had already declared the entity in the persistence.xml file.
At the end the whole problem was simply that the name of the entity is case sensitive on my system.
This jpql was wrong
SELECT u FROM user u WHERE userId = 1?
But this one works fine
SELECT u FROM User u WHERE userId = 1?

Categories