Cannot apply Flyway migration for a PostgreSQL table - java

In my Java app, I have the following migration file:
-- code omitted for brevity
create table if not exists demo_table
(
id bigint not null,
"company" varchar(50) not null,
"name" varchar(50) not null
);
create unique index if not exists demo_table_uuid_company_key
on demo_table (uuid, "company");
create index if not exists demo_table_name_company_key
on demo_table ("name", "company");
Although I can run the sql part part part or at a time on PostgreSQL query window, when running my Java app, it throws the following error:
"Unable to create index (name, company) on table demo_table: database column 'name' not found. Make sure that you use the correct column name which depends on the naming strategy in use (it may not be the same as the property name in the entity, especially for relational types)"
I tried many thing e.g. removing the related migration row from flyway_schema_history table, delete indexes on demo_table, etc. But still the same error. If I try to remove double quotes ("") from name, it gives checksum error. So, as the name is reserve word, I use with double quotes. How can I fix it?
On the other hand, I am not sure if I should change these parameters on application.yml:
spring:
flyway:
enabled: true
jpa:
hibernate:
ddl-auto: update

Some minor issues with the script:
Missing comma on first column of create.
This column is also called id but the index references uuid.
Resolving this allowed the script to work perfectly for me (with the quotes as you have them)
If you make these changes and get a checksum error, please run flyway repair

Related

Query for the allowed values in a constraint

I want to extract values from a CHECK constraint on a database table. The code is:
CONSTRAINT Shop_check_serviceType CHECK (service_type IN ('food or drink', 'entertainment', 'retail'))
In Postgres 12 there is a column named consrc in pg_catalog.pg_constraint. But I use Postgres 14 and I don't know how to extract the values there. I have tried to search the manual without success.
Use the dedicated function pg_get_constraintdef() to reverse-engineer the SQL-DDL code of constraint definition.
SELECT pg_get_constraintdef(oid)
FROM pg_catalog.pg_constraint
WHERE contype = 'c' -- CHECK constraint
AND conrelid = 'public.my_table'::regclass -- your table name here
AND connname = 'shop_check_servicetype'; -- lower-cased?
If you did not double-quote the constraint name "Shop_check_serviceType" it has been converted to lower-case.
Related:
Delete rows with foreign key in PostgreSQL
BTW, the (redundant) column consrc existed up to Postgres 11 and had already been dropped from pg_catalog.pg_constraint in Postgres 12. pg_get_constraintdef() reproduces what used to be in that column.
Quoting the release notes of Postgres 12:
Remove obsolete pg_constraint.consrc column (Peter Eisentraut)
This column has been deprecated for a long time, because it did not
update in response to other catalog changes (such as column
renamings). The recommended way to get a text version of a check
constraint's expression from pg_constraint is pg_get_expr(conbin, conrelid). pg_get_constraintdef() is also a useful alternative.

Insert Returning Query For MySQL in JOOQ

am trying to use the following code to get the auto generated id . My back end is MySQL. Code looks like this
Record record = create.insertInto(CANDIDATE, CANDIDATE.FIRST_NAME,
CANDIDATE.LAST_NAME,CANDIDATE.EXTRACTED_NAME)
.values("Charlotte", "Roche","Charlotte Roche")
.returning(CANDIDATE.ID)
.fetchOne();
System.out.println(record.getValue(CANDIDATE.ID));
I am getting NullPointerException. I took a look at http://www.jooq.org/javadoc/latest/org/jooq/InsertReturningStep.html .
It says
Derby, H2, Ingres, MySQL, SQL Server only allow for retrieving IDENTITY column values as "generated key". If other fields are requested, a second statement is issued. Client code must assure transactional integrity between the two statements.
As per my understanding in Mysql auto_increment works as IDENTITY. Can anybody please throw some light on how to achieve this for MySQL
I have taken a look at this SO Question on a similar topic and tried following
Result<?> record =
create.insertInto(CANDIDATE, CANDIDATE.FIRST_NAME, CANDIDATE.LAST_NAME,CANDIDATE.EXTRACTED_NAME)
.values("Charlotte", "Roche","Charlotte Roche")
.returning(CANDIDATE.ID)
.fetch();
System.out.println(record.size());
Though it inserts record in the backend but it prints the record.size() as zero
I'm know that I'm late for the party.
But I hope I can help someone with similar problem,
Derby, H2, Ingres, MySQL, SQL Server only allow for retrieving IDENTITY column values as "generated key". If other fields are requested, a second statement is issued. Client code must assure transactional integrity between the two statements.
The words "generated key" is the problem.
You can check if your table id is AUTO_INCREMENT or not by using SHOW CREATE TABLE $table_name. I think it is not.
P/s: I'm using MySQL
Just did a test inserting a record and retrieving the generated id from within a Spring service without any problem.
So yes, auto_increment in MySQL works as IDENTITY with jOOQ.
The MySQL table looks like this:
CREATE TABLE persons (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`first_name` varchar(64) NOT NULL,
`last_name` varchar(64) NOT NULL,
primary key(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
and the service like this:
public Result<PersonsRecord> insertPerson(String firstName, String lastName) {
Result<PersonsRecord> result =
dsl
.insertInto(
PERSONS,
PERSONS.FIRST_NAME,
PERSONS.LAST_NAME)
.values(
firstName,
lastName)
.returning(PERSONS.ID)
.fetch();
logger.debug("Person ID: " + result.getValue(0, PERSONS.ID));
return result;
}
The generated id is available straight away after executing the insert:
Person ID: 4
Maybe there is a problem with transaction.
Insert might not yet persisted those values in database, so nothing is fetched.
Also I think that IDENTITY in case of MySQL is not made by AUTO_INCREMENT but PRIMARY KEY (...)
https://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html

Renaming a column in sql using jdbc

I created a table (using NetBeans I went to Databases, into jdbc, into app and created a table). I am 80% sure this is a SQL table but I could be wrong.
I named one of my columns as secretQuestion but now I need to change it to securityQuestion.
I looked online and found the following:
ALTER table app.mytable CHANGE secretQuestion to securityQuestion;
ALTER table app.mytable RENAME secretQuestion to securityQuestion varchar (100);
neither CHANGE nor RENAME are recognized.
I am a slow-witted newbie so be very specific in your answer so that I can follow along!
I am using Derby!
See here.
RENAME COLUMN statement
Syntax
RENAME COLUMN table-Name.simple-Column-Name TO simple-Column-Name
Examples
To rename the manager column in table employee to supervisor, use the
following syntax:
RENAME COLUMN EMPLOYEE.MANAGER TO SUPERVISOR
i have one syntax please remove 'to' keyword. it worked for me. Be sure about the table name and old column name
ALTER TABLE tablename CHANGE name newname DATATYPE;

GORM properties and Postgres fields is domain data type

I just want to know if it possible to map GORM properties to fields in Postgres table where the data type is the postgres domain. I am getting an error when it is validating.
Thanks
Domain class:
class Userprofile {
long iduser
String username
static mapping = {
datasource 'ALL'
id name: 'iduser'
version false
}
}
Table in postgres:
security.userprofile
(
iduser "Primary Key Id" NOT NULL DEFAULT nextval('security.userprofile_seq'::regclass),
username "General Name" NOT NULL,
)
CREATE DOMAIN "Primary Key Id" AS bigint;
CREATE DOMAIN "General Name" AS character varying(100) COLLATE pg_catalog."default";
I have set the dbCreate to "validate" in datasource and i was getting this error message when validating the db:
Caused by HibernateException: Wrong column type in userprofile for column iduser. Found: primary, expected: int8
I am not entirely familiar with GORM validations. There might have to be some additional logic set up to map in the validation rules. However one thing about your error jumped out at me right away.
Caused by HibernateException: Wrong column type in userprofile for column iduser. Found: primary, expected: int8
Now, your domain isn't even "primary" but rather "Primary Key Id." So GORM is not only failing to map it, but is failing even to find the right label.
The first thing I would look at doing is change your naming convention so that it is all lower cases and _'s. The domains become primary_key_id and general_name. See how much further this gets you and then explore what else you have to do to get GORM to handle it.

Spring's JdbcDaoSupport (using MySQL Connector/J) fails after executing sql that adds FK

I am using Spring's JdbcDaoSupport class with a DriverManagerDataSource using the MySQL Connector/J 5.0 driver (driverClassName=com.mysql.jdbc.driver). allowMultiQueries is set to true in the url.
My application is an in-house tool we recently developed that executes sql scripts in a directory one-by-one (allows us to re-create our schema and reference table data for a given date, etc, but I digress). The sql scripts sometime contain multiple statements (hence allowMultiQueries), so one script can create a table, add indexes for that table, etc.
The problem happens when including a statement to add a foreign key constraint in one of these files. If I have a file that looks like...
--(column/constraint names are examples)
CREATE TABLE myTable (
fk1 BIGINT(19) NOT NULL,
fk2 BIGINT(19) NOT NULL,
PRIMARY KEY (fk1, fk2)
);
ALTER TABLE myTable ADD CONSTRAINT myTable_fk1
FOREIGN KEY (fk1)
REFERENCES myOtherTable (id)
;
ALTER TABLE myTable ADD CONSTRAINT myTable_fk2
FOREIGN KEY (fk2)
REFERENCES myOtherOtherTable (id)
;
then JdbcTemplate.execute throws an UncategorizedSqlException with the following error message and stack trace:
Exception in thread "main" org.springframework.jdbc.UncategorizedSQLException: StatementCallback; uncategorized SQLException for SQL [ THE SQL YOU SEE ABOVE LISTED HERE ];
SQL state [HY000]; error code [1005]; Can't create table 'myDatabase.myTable' (errno: 150); nested exception is java.sql.SQLException: Can't create table 'myDatabase.myTable' (errno: 150)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
and the table and foreign keys are not inserted.
Also, especially weird: if I take the foreign key statements out of the script I showed above and then place them in their own script that executes after (so I now have 1 script with just the create table statement, and 1 script with the add foreign key statements that executes after that) then what happens is:
tool executes create table script, works fine, table is created
tool executes add fk script, throws the same exception as seen above (except errno=121 this time), but the FKs actually get added (!!!)
In other words, when the create table/FK statements are in the same script then the exception is thrown and nothing is created, but when they are different scripts a nearly identical exception is thrown but both things get created.
Any help on this would be greatly appreciated. Please let me know if you'd like me to clarify anything more.
Some more info:
1) This only happens on my box. My coworker does not get the same problem.
2) The script that forces the tool to error works fine when executed from the mysql command line using the "script" command
My God.
http://bugs.mysql.com/bug.php?id=41635
and
[2nd link removed because spam filter isn't letting me add 2 links. Search Google for "mysql connector / j errno 150" and it's the 3rd result]
...
Looks like mySql5.1 has a bug with its jdbc connector where it bombs where an alter statement to add a FK is in a script with any other statement.
When I broke out my 3 statements into 3 scripts, it worked (the way I was trying before with the 2 fk statements in their own script still bombed because they were sharing a script!!). Also, my coworker is using MySql5.0, so it didn't affect him.
Holy Cow, that was a fun 5 hours.

Categories