Spring Boot fails to create database schema - postgresql

I have the following entities in my Spring Boot web application all defined in the entities package:
AccessPath.java
Component.java
ComponentInstance.java
ComponentOrder.java
Customer.java
HardwareComponent.java
HardwareGraphicsComponent.java
HardwareProcessingComponent.java
HardwareRamComponent.java
HardwareStorageComponent.java
Invoice.java
Manager.java
Order.java
Product.java
Report.java
ScmManager.java
ScmStaff.java
SoftwareComponent.java
Staff.java
Supplier.java
User.java
WarehouseManager.java
I'm using a properly configured PostgreSQL instance as the database:
spring.thymeleaf.cache=false
#
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/foundationdb
spring.datasource.username=foundationdb
spring.datasource.password=
#
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
When running the application with gradle bootRun I get a lot of error messages regarding invalid SQL statements. It seems like the framework is trying to create the tables in the wrong order and basically fails to create tables for any entity with some sort of relationship. For instance the SQL for creating the order tables fails with the following error most likely because the customer table to which order has a foreign key isn't created yet.
2017-06-09 10:51:35.737 ERROR 85908 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000389: Unsuccessful: create table order (id int8 not null, assembly_date date, confirmation_date date, creation_date date, shipping_date date, status varchar(255), customer_username varchar(255), product_id int8, primary key (id))
2017-06-09 10:51:35.737 ERROR 85908 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : ERROR: syntax error at or near "order"
The only tables created at the end are these:
List of relations
Schema | Name | Type | Owner
--------+-----------------------------+-------+--------------
public | component | table | foundationdb
public | component_instance | table | foundationdb
public | component_order | table | foundationdb
public | invoice | table | foundationdb
public | product | table | foundationdb
public | product_software_components | table | foundationdb
public | report | table | foundationdb
public | supplier | table | foundationdb
My entities were scattered across different packages at first and I tried putting them all in a single package to streamline the process but that didn't help.
This is definitely a framework related issue as testing with in-memory h2 or HSQLDB instances results in similar errors.
The source code for all these classes is available here:
https://gist.github.com/Parsoa/f463fbef548f3a678c1e067e9aad5b21
Any help is appreciated.

order is a reserved SQL keyword (order by ...). Choose another name for your table.
As the error message shows, it has nothing to do with foreign keys:
ERROR: syntax error at or near "order"

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/

Why is id as SERIAL discontinuous values after failover in RDS Aurora PostgreSQL?

I'm testing failover using RDS Aurora PostgreSQL.
First, create RDS Aurora PostgreSQL and access the writer cluster to create users table.
$ CREATE TABLE users (
id SERIAL PRIMARY KEY NOT NULL,
name varchar(10) NOT NULL,
createAt TIMESTAMP DEFAULT Now() );
And I added one row and checked the table.
$ INSERT INTO users(name) VALUES ('test');
$ SELECT * FROM users;
+----+--------+----------------------------+
| id | name | createdAt |
+----+--------+----------------------------+
| 1 | test | 2022-02-02 23:09:57.047981 |
+----+--------+----------------------------+
After failover of RDS Aurora Cluster, I added another row and checked the table.
$ INSERT INTO users(name) VALUES ('temp');
$ SELECT * FROM users;
+-----+--------+----------------------------+
| id | name | createdAt |
+-----+--------+----------------------------+
| 1 | test | 2022-02-01 11:09:57.047981 |
| 32 | temp | 2022-02-01 11:25:57.047981 |
+-----+--------+----------------------------+
After failover, the id value that should be 2 became 32.
Why is this happening?
Is there any way to solve this problem?
That is to be expected. Index modifications are not WAL logged whenever nextval is called, because that could become a performance bottleneck. Rather, a WAL record is written every 32 calls. That means that the sequence can skip some values after a crash or failover to the standby.
You may want to read my ruminations about gaps in sequences.

Executed create index concurrently statmt & it was disconnected session due to timeout error.but I do see in pg_stat_activity,it is in running state

I have executed create an index on a big table from pgAdmin, and in a while, I lost connection to the server, so the execution window closed in pgAdnin. Then I reconnected to the server, and when checked pg_stat_activity, I do see that the create index statement is running (active) state, I just wondering to know whether this index being creating or stuck somewhere?
client disconnected with error,
cancelling statement due to statement timeout
when I reconnected to the server, in pg_stat_activity.
31937 "edsadmin" "09:54:44.280176" "CREATE INDEX CONCURRENTLY idx_src_record_date
ON pcd_t.l_esd_detail_report USING btree
(src_record_date COLLATE pg_catalog."default")
TABLESPACE pg_default;"
I'm really confused here wheather it is createing or not.
Late answer, but relevant none-the-less.
Based on my anecdotal experience right now, the index creation persists beyond the lifetime of the client.
I did the following:
database=> CREATE INDEX CONCURRENTLY IX_myIndex on table(column, column2);
It paused for a few minutes, then:
SSL SYSCALL error: EOF detected
The connection to the server was lost. Attempting reset: Succeeded.
psql (14.2 (Debian 14.2-1.pgdg110+1), server 10.18)
Immediately after reconnecting, I ran:
database=> \d table
Table "public.table"
Column | Type | Collation | Nullable |
Default
-----------------+-----------------------------+-----------+----------+---------
... blah blah blah ...
Indexes:
"IX_myIndex" btree (column, column2) INVALID
I waited a few more minutes, then checked again:
database=> \d table
Table "public.table"
Column | Type | Collation | Nullable |
Default
-----------------+-----------------------------+-----------+----------+---------
... blah blah blah ...
Indexes:
"IX_myIndex" btree (column, column2)
So, your index is likely fine.

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

postgres schema not found when create with upper case

I am trying to create app using OpenJPA & Postgres 9.2.xx, Currently facing issue at DB level
1) Created schema say PCM:-
CREATE SCHEMA PCM
2) Tried create table :-
CREATE TABLE PCM.USER_PROFILE (
USER_PROFILE_ID BIGINT NOT NULL,
USER_FNAME VARCHAR(60),
USER_LNAME VARCHAR(60)
};
Got error "pcm" schema does not exists
Then tried creating table :-
CREATE TABLE "PCM.USER_PROFILE" (
USER_PROFILE_ID BIGINT NOT NULL,
USER_FNAME VARCHAR(60),
USER_LNAME VARCHAR(60)
};
Table is created successful,
If I list the schema:-
[postgres#DBMigration ~] $ psql -c "\dn"
List of schemas
Name | Owner
--------+----------
pcm | dbadmin
public | postgres
B) In persistence.xml , I have entered configuration
<property name="openjpa.jdbc.Schema" value="PCM" />
Now I am getting issue in OpenJPA stating schema is not present.
I tried refering here, but no success.
I have tried entering schema name in configuration as '\"PCM\"', "\"PCM\"", '\"pcm\"', "\"pcm\"".
Not sure where am I going wrong.
I need suggestion/help,
1) how or what is proper standard to create schema in Postgres & refer while creating table.
2) Is my entry in persistence.xml correct? Then why its not identifying the schema
Object names in Postgres when not quoted are implicitly converted to lower case.
When you create a table the way you did below with quotation mark on "PCM.USER_PROFILE" then the table is created in default public schema with the name of "PCM.USER_PROFILE".
CREATE TABLE "PCM.USER_PROFILE" (
USER_PROFILE_ID BIGINT NOT NULL,
USER_FNAME VARCHAR(60),
USER_LNAME VARCHAR(60)
);
However, your create statement mentioned in the post is completely valid (with the exception of changing } to ) at the end of command:
CREATE TABLE PCM.USER_PROFILE (
USER_PROFILE_ID BIGINT NOT NULL,
USER_FNAME VARCHAR(60),
USER_LNAME VARCHAR(60)
);
It creates user_profile table under pcm schema succesfully.
The error that I did was created schema outside database environment & root user. When we tried running select * from information_schema.schemata; under both users (root & db user) the schema was not listing.
Hence create schema under a DB by running query
psql -U [dbUser] -d [database] -c "CREATE SCHEMA pcm;"
or
psql -h localhost -U [dbUser] -d [database]
[database]#=> CREATE SCHEMA pcm;
Try running query to test if schema is loaded successfully under database & dbowner user.
[database]#=> select * from information_schema.schemata;