Switching from H2 to PostgreSQL with spring boot - java

I have a spring boot application working fine on a H2 DB. If I want to switch to postgresQL I get errors.
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
Errors:
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "drop table if exists
user cascade" via JDBC Statement
...
Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "user"
...
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create table user (id int8 not null, active int4 not null, first_name varchar(255), last_name varchar(255), password varchar(255), role varchar(255), username varchar(255), primary key (id))" via JDBC Statement

I think this is because user is a reserved word in PostrgeSQL.
In order to create a table with such name, try quote it (that is, create table "user"...)
Enclosing all the objects' names in 'ANSI quotes' is generally a good idea if you want an interoperability between different databases.

Related

One to one relationship Error on Postgresql

I would like to seek your insights regarding the error I'm encountering with my postgresql commands.
Basically, what I want to achieve is to create a "booking" entity with one to one relationship to another table called "booking details". But flyway won't migrate my schema with the following error:
Caused by: org.flywaydb.core.internal.sqlscript.FlywaySqlScriptException:
Migration V0__Initial.sql failed
--------------------------------
SQL State : 42S02
Error Code : 42102
Message : Table "BOOKING_DETAILS" not found; SQL statement:
ALTER TABLE booking ADD CONSTRAINT FK_BOOKING_ON_BOOKING_DETAILS FOREIGN KEY (booking_details_id) REFERENCES booking_details (booking_entity_id) [42102-214]
Line : 16
Statement : ALTER TABLE booking ADD CONSTRAINT FK_BOOKING_ON_BOOKING_DETAILS FOREIGN KEY (booking_details_id) REFERENCES booking_details (booking_entity_id)
Here is my postgresql commands:
DROP SEQUENCE IF EXISTS booking_transaction_sequence;
DROP TABLE IF EXISTS booking;
CREATE SEQUENCE IF NOT EXISTS booking_transaction_sequence START WITH 1000 INCREMENT BY 100;
CREATE TABLE booking (
id BIGINT NOT NULL,
booking_number VARCHAR(255),
booking_status VARCHAR(255),
processed_by VARCHAR(255),
created_at TIMESTAMP WITHOUT TIME ZONE,
booking_details_id BIGINT,
CONSTRAINT pk_booking PRIMARY KEY (id)
);
ALTER TABLE booking ADD CONSTRAINT FK_BOOKING_ON_BOOKING_DETAILS FOREIGN KEY (booking_details_id) REFERENCES booking_details (booking_entity_id);
DROP SEQUENCE IF EXISTS booking_details_transaction_sequence;
DROP TABLE IF EXISTS booking_details;
CREATE SEQUENCE IF NOT EXISTS booking_details_transaction_sequence START WITH 1000 INCREMENT BY 100;
CREATE TABLE booking_details (
booking_entity_id BIGINT NOT NULL,
sender_name VARCHAR(255),
item_details VARCHAR(255),
pickup_address VARCHAR(255),
rider_name VARCHAR(255),
delivery_address VARCHAR(255),
cancellation_reason VARCHAR(255),
CONSTRAINT pk_booking_details PRIMARY KEY (booking_entity_id)
);
ALTER TABLE booking_details ADD CONSTRAINT FK_BOOKING_DETAILS_ON_BOOKINGENTITY FOREIGN KEY (booking_entity_id) REFERENCES booking (id);
I would highly appreciate any inputs regarding this. Thank you.
I tried using the "extend" method on my BookingDetails entity to BookingEntity. This run my java springboot application but for some reason I can't fetch data with internal error 500 in postman. So I change my sql commands with the one-to-one relationship mapping but I got the above errors.
Just out of interest - how you're planning to insert new entries given the schema? In order to create booking you'd need to have booking_details created and vice versa.
The error message indicates that the table "BOOKING_DETAILS" is not found when you're trying to create a foreign key constraint in the "booking" table.
You need to make sure that the "booking_details" table is created before creating the foreign key constraint in the "booking" table. You can do this by reordering your migration script to create the "booking_details" table before creating the "booking" table with the foreign key constraint.
Additionally, check that the table name and column name used in the foreign key constraint statement are correct and match the names used in the "booking_details" table.
Solution: put this command on the last part of the sql so that the two tables must be created first before it can be altered.
"ALTER TABLE booking ADD CONSTRAINT FK_BOOKING_ON_BOOKING_DETAILS FOREIGN KEY (booking_details_id) REFERENCES booking_details (booking_entity_id);"

Fix liquibase and Orient DB compatibility

I upgraded liquibase version in my Spring Boot App from 3.10.2 to 4.17.2 and I'm getting error
Suppressed: com.orientechnologies.orient.core.sql.OCommandSQLParsingException: Error parsing query: CREATE TABLE DATABASECHANGELOGLOCK (ID INT NOT NULL, LOCKED BOOLEAN NOT NULL, LOCKGRANTED datetime, LOCKEDBY VARCHAR(255), CONSTRAINT PK_DATABASECHANGELOGLOCK PRIMARY KEY (ID)) Encountered " <CREATE> "CREATE "" at line 1, column 1.Was expecting one of:
<LET> ...
<EXPLAIN> ...
DB name="mdp"
Error Code="1"
at com.orientechnologies.orient.core.sql.parser.OStatementCache.throwParsingException(OStatementCache.java:155)
at com.orientechnologies.orient.core.sql.parser.OStatementCache.parse(OStatementCache.java:147)
at com.orientechnologies.orient.core.sql.parser.OStatementCache.get(OStatementCache.java:86)
at com.orientechnologies.orient.core.sql.parser.OStatementCache.get(OStatementCache.java:65)
at com.orientechnologies.orient.core.sql.OSQLEngine.parse(OSQLEngine.java:80)
at com.orientechnologies.orient.core.db.document.ODatabaseDocumentEmbedded.command(ODatabaseDocumentEmbedded.java:650)
at com.orientechnologies.orient.server.OConnectionBinaryExecutor.executeQuery(OConnectionBinaryExecutor.java:1489)
at com.orientechnologies.orient.client.remote.message.OQueryRequest.execute(OQueryRequest.java:143)
at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.sessionRequest(ONetworkProtocolBinary.java:355)
at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.execute(ONetworkProtocolBinary.java:239)
at com.orientechnologies.common.thread.OSoftThread.run(OSoftThread.java:67)
As I can see liquibase can not create his own tables. I started getting this error after version update.
Can somebody tell me what can be a reason and how can I fix it. I can provide any information about my app whatever you need. Thanks!

Liquibase is trying to create the databasechangelog table again

In my project I have scripts that create tables, make changes, and so on, now when I add a new migration in a new file in the changeLog, I get an error. In the last migration that I added, there are no errors, because if you delete all tables from the schema and run the project, then everything will work without problems. But this option is not suitable, as a rule. The error occurs precisely when adding a new migration on top of the old one.
[ERROR] Error setting up or running Liquibase:
[ERROR] ??????: ????????? "databasechangelog" ??? ?????????? [Failed SQL: (0) CREATE TABLE databasechangelog (ID VARCHAR(255) NOT NULL, AUTHOR VARCHAR(255) NOT NULL, FILENAME VARCHAR(2
55) 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 V
ARCHAR(255), TAG VARCHAR(255), LIQUIBASE VARCHAR(20), CONTEXTS VARCHAR(255), LABELS VARCHAR(255), DEPLOYMENT_ID VARCHAR(10))]
I use spring boot, postgres in my project. What do you think might be the problem? thanks in advance.
left it in the form of a screen too, suddenly it will be more convenient for someone)
If you already have those spring configurations in your property file, It will create the liquibase tables. Make sure you are not creating it manually again in other liquibase script.
spring.liquibase.database-change-log-lock-table = DATABASECHANGELOGLOCK
spring.liquibase.database-change-log-table = DATABASECHANGELOG

Flyway and PostgreSQL nullable definition of foreign key still generates a non-null constraint

I use Spring Boot and Flyway with this initialization script:
CREATE TABLE ADDRESS(
ID bigserial NOT NULL PRIMARY KEY
);
CREATE TABLE ROLE(
ID bigserial NOT NULL PRIMARY KEY
);
CREATE TABLE PERSON(
ID bigserial NOT NULL PRIMARY KEY,
FIRST_NAME VARCHAR(255),
LAST_NAME VARCHAR(255),
ADDRESS bigserial NOT NULL REFERENCES ADDRESS (ID),
ROLE bigserial REFERENCES ROLE (ID) -- notice here is no 'not null'
);
All the relationship between the tables is that:
Each PERSON has 0-1 ROLE. So, each ROLE belongs to 0-n PERSON. Hence, this relationship is nullable.
Each PERSON has 1 ADDRESS. So, each ADDRESS belongs to 1-n PERSON. Hence, this relationship is not-null.
As soon as I start the application (I have also tried to post the query straight to the PostgreSQL database schema), there is somehow generated constraint not-null between the PERSON and ROLE tables.
Using DataGrip, I select SQL Scripts -> Generate DDL to Query Console and get the DDL for the tables (see below, new lines and roles definitions omitted for sake of brevity).
To my surprise, the NOT NULL is there although I haven't defined such constraint. How to get rid of it aside from altering table?
create table if not exists address
(
id bigserial not null
constraint address_pkey primary key
);
create table if not exists role
(
id bigserial not nullconstraint role_pkey primary key
);
create table if not exists person
(
id bigserial not null
constraint person_pkey primary key,
first_name varchar(255),
last_name varchar(255),
address bigserial not null
constraint person_address_fkey references address,
role bigserial not null -- why is 'not null' here?
constraint person_role_fkey references role
);
The version of PostgreSQL I use (through SELECT version()) is:
PostgreSQL 10.13, compiled by Visual C++ build 1800, 64-bit
"8.1.4. Serial Types":
The data types smallserial, serial and bigserial are not true
types, but merely a notational convenience for creating unique
identifier columns (similar to the AUTO_INCREMENT property supported
by some other databases). In the current implementation, specifying:
CREATE TABLE tablename (
colname SERIAL
);
is equivalent to specifying:
CREATE SEQUENCE tablename_colname_seq AS integer;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
Note the NOT NULL.
Don't use bigserial for the foreign key. That doesn't make much sense. Simply use bigint.
CREATE TABLE IF NOT EXISTS person
(...
role bigint REFERENCES role);
Possible solution 1:
Changing Biserial to Bigint does not remove the null constraint set to foreign key column when running flyway in springboot to write into postgres DB (at least for my case)
postgres:11.3-alphine 3.4
flyway: 8.0.5
To be secure, need to add scripts to alter columns to be nullable
ALTER TABLE mytable ALTER COLUMN mycolumn DROP NOT NULL;
Change Postgres column to nullable
Possible solition 2:
When Spring boot set JPA Hibernate ddl configuration to create, create-drop, update, flyway DB migration script will be updated by JPA entities properties. NOT NULL constraints can be added by JPA entities.
Change JPA Hibernate ddl configuration to none or validate will ensure only flyway script is used to create schema.
JPA Hibernate ddl configuration

SQL syntax error initializing DB before unit Tests

I have created a .sql for preparing my DB for testing.
here a part of the .sql which produces the error:
DROP TABLE IF EXISTS announcement;
CREATE TABLE announcement (
id int(11) NOT NULL AUTO_INCREMENT,
date datetime DEFAULT NULL,
title varchar(255) DEFAULT NULL,
content mediumtext,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
LOCK TABLES announcement WRITE;
INSERT INTO announcement VALUES (1,'2015-07-29 10:59:16','Test Anno ','some text');
UNLOCK TABLES;
when executed in Mysql Workbench this scipt works fine.
however when executed via hibernate:
String sqlScript = readFile("dump.sql", Charset.forName("UTF8"));
//System.err.println(sqlScript);
Query q = em.createNativeQuery("BEGIN " + sqlScript + "END;");
q.executeUpdate();
I get:
2015-08-06 16:15:55 ERROR SqlExceptionHelper:146 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DROP TABLE IF EXISTS announcement;
CREATE TABLE announcement (
id int(11) NO' at line 1
I am using:
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.dialect","org.hibernate.dialect.MySQL5Dialect");
jpaProperties.put("hibernate.enable_lazy_load_no_trans", true);
Can someone help me out here?
thanks.
As stated by mustaccio BEGIN and END statements are not allowed outside of stored procedueres. See: Hibernate multiple native SQL statements

Categories

Resources