play framewok postgresql : Database 'default' needs evolution - postgresql

i deployed my very simple app in heroku by following tutorials
it works well in my localhost when i run it by sbt run
but it crashes on heroku!
here is my 1.sql:
# --- !Ups
create table contact (
id SERIAL UNIQUE,
name varchar(255),
email varchar(255),
phone varchar(255),
constraint pk_contact primary key (id)
);
create sequence contact_seq;
# --- !Downs
drop table if exists contact;
drop sequence if exists contact_seq;
heroku's log:
p.a.d.DefaultDBApi - Database [default] connected at jdbc:postgresql://...
!!! WARNING! This script contains DOWNS evolutions that are likely destructive
[warn] p.a.d.e.ApplicationEvolutions - Your production database [default] needs evolutions, including downs!
drop table if exists contact;
# --- Rev:1,Downs - a56ada6
name varchar(255),
drop sequence if exists contact_seq;
email varchar(255), phone varchar(255),
# --- Rev:1,Ups - 53110fe
create table contact (
);
id SERIAL UNIQUE,
constraint pk_contact primary key (id)
create sequence contact_seq;
[warn] p.a.d.e.ApplicationEvolutions - Run with -Dplay.evolutions.db.default.autoApply=true and -Dplay.evolutions.db.default.autoApplyDowns=true if you want to run them automatically, including downs (be careful, especially if your down evolutions drop existing data)
[info] application - ApplicationTimer demo: Starting application at 2017-04-28T08:59:05.048Z
Oops, cannot start the server.
#73o5pe90c: Database 'default' needs evolution!
and i also added
play.evolutions.db.default.autoApply=true
at end of my aplication.conf

Run with
-Dplay.evolutions.db.default.autoApply=true
and
-Dplay.evolutions.db.default.autoApplyDowns=true
If you want to run them automatically, including downs (be careful, especially if your down evolutions drop existing data).
You can set these by running:
heroku config:set JAVA_OPTS="-Dplay.evolutions.db.default.autoApply=true -Dplay.evolutions.db.default.autoApplyDowns=true"

Related

REVINFO table is missing the sequence "revinfo_seq"

I am migrating to SpringBoot 3.0.1 and updated "hibernate-envers" version to "6.1.6.Final". My DB is PostgreSQL 13.6.
Hibernate is configured to create the DB schema:
spring.jpa.hibernate.ddl-auto:create
After starting the application I get the following error:
pim 2022-12-27 12:00:13,715 WARN C#c7b942ec-33b4-4749-b113-22cbb2946a8d [http-nio-9637-exec-1] SqlExceptionHelper/133 - SQL Error: 0, SQLState: 42P01
pim 2022-12-27 12:00:13,715 ERROR C#c7b942ec-33b4-4749-b113-22cbb2946a8d [http-nio-9637-exec-1] SqlExceptionHelper/138 - ERROR: relation "revinfo_seq" does not exist
Position: 16
The revinfo table look like this:
create table revinfo
(
revision bigint not null
primary key,
client_id varchar(255),
correlation_id varchar(255),
origin varchar(255),
request_id varchar(255),
revision_timestamp bigint not null,
timestamp_utc timestamp with time zone,
user_name varchar(255)
);
The sequence "revinfo_seq" does not exist, but in the old DB structure with envers
5.6.8.Final
and SpringBoot 2.6.6 it didn't exist either without any problems.
What am i Missing?
I tried to toggle the paramter
org.hibernate.envers.use_revision_entity_with_native_id
but it did not help.
You can solve it with this property:
spring.jpa.properties.hibernate.id.db_structure_naming_strategy: legacy
Tested with Spring Boot 3.0.1
Reason:
Hibernate 6 changed the sequence naming strategy, so it was searching for a sequence ending with "_seq".
You can a really detailed explanation here: https://thorben-janssen.com/sequence-naming-strategies-in-hibernate-6/

How do I stop Liquibase updateSQL from generating Start and successful messages that end up in the SQL?

This command:
liquibase --logLevel=off --changeLogFile=./database_change_log.xml --url='offline:postgresql?outputLiquibaseSql=true' updateSql > database_up.sql
generates this:
Starting Liquibase at Thu, 14 Mar 2019 11:29:12 CDT (version 3.6.3 built at 2019-01-29 11:34:48)
-- *********************************************************************
-- Update Database Script
-- *********************************************************************
-- Change Log: ./database_change_log.xml
-- Ran at: 3/14/19, 11:29 AM
-- Against: null#offline:postgresql?outputLiquibaseSql=true
-- Liquibase version: 3.6.3
-- *********************************************************************
CREATE TABLE databasechangelog (ID VARCHAR(255) NOT NULL, AUTHOR VARCHAR(255) NOT NULL, FILENAME VARCHAR(255) NOT NULL, DATEEXECUTED TIMESTAMP WITHOUT TIME ZONE NOT NULL, ORDEREXECUTED INTEGER NOT NULL, EXECTYPE VARCHAR(10) NOT NULL, MD5SUM VARCHAR(35), DESCRIPTION VARCHAR(255), COMMENTS VARCHAR(255), TAG VARCHAR(255), LIQUIBASE VARCHAR(20), CONTEXTS VARCHAR(255), LABELS VARCHAR(255), DEPLOYMENT_ID VARCHAR(10));
-- Changeset ./database_change_log.xml::1::Jim Barrows
CREATE TABLE topic (id UUID NOT NULL, name VARCHAR(100) NOT NULL, description TEXT, CONSTRAINT TOPIC_PKEY PRIMARY KEY (id));
INSERT INTO databasechangelog (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, MD5SUM, DESCRIPTION, COMMENTS, EXECTYPE, CONTEXTS, LABELS, LIQUIBASE, DEPLOYMENT_ID) VALUES ('1', 'Jim Barrows', './database_change_log.xml', NOW(), 1, '8:7b01de4dcdab4ed25f79ce192ba538f6', 'createTable tableName=topic', '', 'EXECUTED', NULL, NULL, '3.6.3', '2580954069');
Liquibase command 'updateSql' was executed successfully.
The problem is that I don't want the "Starting liquibase" or success lines in the SQL.
Note: off is from the docs: --logLevel= Execution log level (debug, info, warning, severe, off).
I've tried to use "severe" & "error" as well
This is version 3.6.3, and version 3.5.3 does not do this. How do I fix this?
Someone has already opened a bug ticket for this: https://liquibase.jira.com/browse/CORE-3342.
This seemingly got introduced from version 3.6 on.
EDIT:
So maybe downgrade or even better propose a fix in form of a pull request. :-)
Wondering about why updateSQL output would be written with a logging framework
I just discovered that you could pass in migrationSqlOutputFile as a parameter instead of redirecting the standard output to a file. That way the logging should not be mingled with output from updateSQL.
(Have not tried this though.)
Use --outputFile option in the liquibase command to direct the sql statements to a file. I use liquibase version 3.7.0 and this option works.
Since 3.4.0 release of Liquibase, you can use outputFile flag. Details are here:
https://www.liquibase.org/2015/07/without-a-connection.html

Spring Boot 2 - H2 Database - #SpringBootTest - Failing on org.h2.jdbc.JdbcSQLException: Table already exists

Unable to test Spring Boot & H2 with a script for creation of table using schema.sql.
So, what’s happening is that I have the following properties set:
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.initialization-mode=always
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.platform=h2
spring.datasource.url=jdbc:h2:mem:city;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.generate-ddl=false
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
and, I expect the tables to be created using the schema.sql. The application works fine when I run gradle bootRun. However, when I run tests using gradle test, my tests for Repository passes, but the one for my Service fails stating that it’s trying to create the table when the table already exists:
Exception raised:
Caused by: org.h2.jdbc.JdbcSQLException: Table "CITY" already exists;
SQL statement:
CREATE TABLE city ( id BIGINT NOT NULL, country VARCHAR(255) NOT NULL, map VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, state VARCHAR(2555) NOT NULL, PRIMARY KEY (id) ) [42101-196]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.command.ddl.CreateTable.update(CreateTable.java:117)
at org.h2.command.CommandContainer.update(CommandContainer.java:101)
at org.h2.command.Command.executeUpdate(Command.java:260)
at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:192)
at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:164)
at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:95)
at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java)
at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:471)
... 105 more
The code is setup and ready to recreate the scenario. README has all the information ->
https://github.com/tekpartner/learn-spring-boot-data-jpa-h2
If the tests are run individually, they pass. I think the problem is due to schema.sql being executed twice against the same database. It fails the second time as the tables already exist.
As a workaround, you could set spring.datasource.continue-on-error=true in application.properties.
Another option is to add the #AutoConfigureTestDatabase annotation where appropriate so that a unique embedded database is used for each test.
There are 2 other possible solutions you could try:
Add a drop table if exists [tablename] in your schema.sql before you create the table.
Change the statement from CREATE TABLE to CREATE TABLE IF NOT EXISTS

Play evolution not loading 1.sql

I'm running Play with Slick integration, Evolutions and an H2 database. When starting Play in dev mode and visiting localhost:9000 (I am using https) I am told database "default" needs evolution. However the script I have in conf/evolutions/default/1.sql is not display below. Rather it only shows:
1# --- Rev:1,Ups - da39a3e
However my script reads:
# --- ! Ups
create table "USERS" ("ID" VARCHAR NOT NULL PRIMARY KEY, "ACTION" VARCHAR);
# --- ! Downs
drop table "USERS";
Naturally all transactions on this table fail. Am I missing a bit of configuration?
There must not be a space between the exclamation mark and the command:
# --- ! Ups
Wrong!
# --- !Ups
Right!

Evolution not seen

I have began a Play Scala project and made it have a database by uncommenting in application.conf:
default.driver = org.h2.Driver
default.url = "jdbc:h2:mem:play"
Then, I created an evolution in conf/evolutions/default/1.sql:
CREATE SEQUENCE task_id_seq;
CREATE TABLE task (
id integer NOT NULL DEFAULT nextval('task_id_seq'),
label varchar(255)
);
# --- !Downs
DROP TABLE task;
DROP SEQUENCE task_id_seq;
So, when I am accessing localhost:9000 I am expecting to see the message:
Database default needs evolution!. However, this does not appear.
I am running in development mode and I don't have the code evolutionplugin=disabled anywhere in my project.
Why is the evolution not seen?
You need to add evolutions to the list of your library dependencies, as described in the docs https://www.playframework.com/documentation/2.4.0/Evolutions.