I have created a an sql script (using mysqldump) to determine my base version of my database. I use this script with flywaydb to totally manage the db creation and other migration actions. The script contains of several tables some of them are fk's to others. the order in which they appear in the sql script generated by mysqldump is the following (only two of the tables appear that are causing the issue described later below)
CREATE TABLE `signaling_interface` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`test_server_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UK_sigInterfaceConstraint` (`test_server_id`),
KEY `FK_3crdx5y8had0g1mit1k2gebt5` (`test_server_id`),
CONSTRAINT `FK_3crdx5y8had0g1mit1k2gebt5` FOREIGN KEY (`test_server_id`) REFERENCES `test_server` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `test_server` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UK_3754w88bn333h1dgambvwj6i8` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I want to Junit test my migrations and chose h2 in memory database to do that. But when I try to migrate it gives me an error when creating signaling_interface table because test_server does not exist. It doesn't give me this error when executing migrations in MySQL. Is there a difference between mysql and h2?
Related
I have an application which starts (AppStarter) a web server with a web application. The Web Application has migration scripts (flyway).
I want to write some data from AppStarter through JDBC in a table. But I want to create the table if it does not exist. The table also has some constraints.
Within the AppStarter I execute following command:
CREATE CACHED TABLE PUBLIC.CORE_USERROLE_TO_PARAMETER (
ID VARCHAR(32) PRIMARY KEY NOT NULL,
VERSION INTEGER,
USER_ID VARCHAR(32)NOT NULL,
ROLE_ID VARCHAR(32) NOT NULL,
PARAMETER VARCHAR(255) NOT NULL
);
ALTER TABLE PUBLIC.CORE_USERROLE_TO_PARAMETER ADD CONSTRAINT PUBLIC.CURTBP_USER_ID FOREIGN KEY(USER_ID) REFERENCES PUBLIC.CORE_USER(ID) NOCHECK;
ALTER TABLE PUBLIC.CORE_USERROLE_TO_PARAMETER ADD CONSTRAINT PUBLIC.CURTBP_ROLE_ID FOREIGN KEY(ROLE_ID) REFERENCES PUBLIC.CORE_USER_ROLE(ID) NOCHECK;
The web app also reads some information from this table and creates the tables.
Now I have a sql migration script
CREATE CACHED TABLE IF NOT EXISTS PUBLIC.CORE_USERROLE_TO_PARAMETER (
ID VARCHAR(32) PRIMARY KEY NOT NULL,
VERSION INTEGER,
USER_ID VARCHAR(32)NOT NULL,
ROLE_ID VARCHAR(32) NOT NULL,
PARAMETER VARCHAR(255) NOT NULL
);
But how do I create the constraint only if they does not already exist?
Thanks in advance
Currently I can get if the constraints exists with
select * from INFORMATION_SCHEMA.CONSTRAINTS WHERE CONSTRAINT_NAME='CURTRP_USER_ID'
but how do I build this into a if query with H2
Edit:
I could move the constraint part in total to the migration script, but this seems somehow wrong.
I am working with H2 Database.
Following my comment, this should be possible:
ALTER TABLE PUBLIC.CORE_USERROLE_TO_PARAMETER
ADD CONSTRAINT IF NOT EXISTS PUBLIC.CURTBP_USER_ID
FOREIGN KEY(USER_ID) REFERENCES PUBLIC.CORE_USER(ID) NOCHECK;
ALTER TABLE PUBLIC.CORE_USERROLE_TO_PARAMETER
ADD CONSTRAINT IF NOT EXISTS PUBLIC.CURTBP_ROLE_ID
FOREIGN KEY(ROLE_ID) REFERENCES PUBLIC.CORE_USER_ROLE(ID) NOCHECK;
Use this query to get the foreign key constraints
SELECT * FROM INFORMATION_SCHEMA.CONSTRAINTS WHERE CONSTRAINT_TYPE = 'REFERENTIAL'
You can try ALTER TABLE IF EXISTS like CREATE IF EXISTS. If its a responsibility of your application only, and not handled by another app or script.
MySQL Version: 5.7.17 on Windows 10
I used the following SQL statement to generate a table.
CREATE TABLE `attributes` (
`id` varchar(36) NOT NULL,
`name` varchar(255) NOT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`),
KEY `name_idx` (`name` DESC)
)
I tried that statement from Java Code. I tried this statement also from MySQL Workbench.
It never creates a descending index on name.
Is this a known issue?
Have I made a mistake?
I'm trying to embed h2 to test my mysql-application (integration-test)
I added com.h2database:h2:1.3.170 via maven and run the following code:
public class InMemoryTest
{
#Test
public void test() throws Exception {
Class.forName("org.h2.Driver");
Connection conn = DriverManager.
getConnection("jdbc:h2:mem:test;MODE=MySQL;IGNORECASE=TRUE;INIT=RUNSCRIPT FROM 'src/test/resources/test.sql'");
}
}
which gives me the following Exception:
Syntax error in SQL statement "
CREATE TABLE IF NOT EXISTS ""usr_avatar"" (
""usr_avatar_id"" INT(11) NOT NULL AUTO_INCREMENT,
""usr_avatar_user_id"" INT(11) NOT NULL,
""usr_avatar_img"" BLOB NOT NULL,
PRIMARY KEY (""usr_avatar_id""),
UNIQUE KEY ""usr_avatar_id_UNIQUE"" (""usr_avatar_id""),
UNIQUE KEY ""usr_avatar_user_id_UNIQUE"" (""usr_avatar_user_id""),
KEY ""usr_user_id"" (""usr_avatar_user_id""),
KEY ""fk_user_id"" (""usr_avatar_user_id"")
) AUTO_INCREMENT[*]=1 ";
Apparently, the "AUTO_INCREMENT" causes this?
Since this is valid MySQL (I exported the dump from my real database using MySQL Workbench), I'm a bit confused since h2 claims to support MySQL?
Here are a few lines from the .sql:
DROP TABLE IF EXISTS `usr_avatar`;
CREATE TABLE IF NOT EXISTS "usr_avatar" (
"usr_avatar_id" int(11) NOT NULL AUTO_INCREMENT,
"usr_avatar_user_id" int(11) NOT NULL,
"usr_avatar_img" blob NOT NULL,
PRIMARY KEY ("usr_avatar_id"),
UNIQUE KEY "usr_avatar_id_UNIQUE" ("usr_avatar_id"),
UNIQUE KEY "usr_avatar_user_id_UNIQUE" ("usr_avatar_user_id"),
KEY "usr_user_id" ("usr_avatar_user_id"),
KEY "fk_user_id" ("usr_avatar_user_id")
) AUTO_INCREMENT=1 ;
DROP TABLE IF EXISTS `usr_restriction`;
CREATE TABLE IF NOT EXISTS "usr_restriction" (
"usr_restriction_id" int(11) NOT NULL AUTO_INCREMENT,
"usr_restriction_user_id" int(11) DEFAULT NULL,
"usr_restriction_ip" varchar(39) DEFAULT NULL,
"usr_restriction_valid_from" date NOT NULL,
"usr_restriction_valid_to" date DEFAULT NULL,
PRIMARY KEY ("usr_restriction_id"),
UNIQUE KEY "usr_restriction_id_UNIQUE" ("usr_restriction_id"),
KEY "user_id" ("usr_restriction_user_id"),
KEY "usr_user_id" ("usr_restriction_user_id")
) AUTO_INCREMENT=1 ;
What are my options? Should I export the dump with a different software and force it to be plain SQL? Which software could do that? Or am I doing something wrong?
The problem is that H2 doesn't support AUTO_INCREMENT=1, which you have specified in the SQL statement. Try removing it. I don't think it's necessary for MySQL either.
The source SQL exported from MySQL has double-quotes surrounding it's literals. The first DROP statement also has a "back-tick" (`). But when H2 is reporting the error, H2 is showing the literals surrounded by double-double quotes. I think this is the problem.
Try a couple of things. First, take the back-tick in the DROP statement and convert it to single quotes. If that doesn't work, convert all of the double-quotes to single-quotes. If that doesn't work, remove all of the quotes.
I think H2 is trying to create tables with the double-quotes as a part of the actual table names/column names and this is causing it to bomb.
H2 doesn't support AUTO_INCREMENT=1.
Use this instead:
ALTER TABLE table_name ALTER COLUMN id RESTART WITH 1;
I have a table which has a field ID as a primary key and another field PID as the Foreign Key to the ID Field. Both are of long DataTypes.
So this is my table struct
CREATE TABLE `myobj` (
`ID` BIGINT(100) NOT NULL AUTO_INCREMENT,
`FRIENDLY_NAME` VARCHAR(100) DEFAULT NULL,
`PARENT_ID` BIGINT(100) DEFAULT NULL,
`PARENT` VARCHAR(100) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `PARENT_ID` (`PARENT_ID`),
CONSTRAINT `myobj_ibfk_1` FOREIGN KEY (`PARENT_ID`) REFERENCES `myobj` (`ID`) ON DELETE CASCADE
) ENGINE=INNODB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
I use Hibernate as ORM to insert into the MySQL DB. The problem is
When One or more of the records which will be top level with no parent id, an error occurs with insert top-level records. It looks like in case of no parent id
it will accept only NULL.
But from Java Application code perspective, the datatype is long and hence when i insert an object through Hibernate, with default value as 0 ,it looks like a constraint violation
Cannot add or update a child row: a
foreign key constraint fails
(genericdb.myobj, CONSTRAINT
myobj_ibfk_1 FOREIGN KEY
(PARENT_ID) REFERENCES myobj
(ID) ON DELETE CASCADE)
This problem occurs also when setting 0 as the value thru sql CLI.
Second Secnario:
Also tried setting the Default Value for PARENT_ID as 0.
CREATE TABLE `myobj` (
`ID` BIGINT(100) NOT NULL AUTO_INCREMENT,
`FRIENDLY_NAME` VARCHAR(100) DEFAULT NULL,
`PARENT_ID` BIGINT(100) DEFAULT '0',
`PARENT` VARCHAR(100) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `PARENT_ID` (`PARENT_ID`),
CONSTRAINT `myobj_ibfk_1` FOREIGN KEY (`PARENT_ID`) REFERENCES `myobj` (`ID`) ON DELETE CASCADE
) ENGINE=INNODB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
SO when i insert 0 into Parent_ID field, still error
Cannot add or update a child row: a
foreign key constraint fails
(genericdb.myobj, CONSTRAINT
myobj_ibfk_1 FOREIGN KEY
(PARENT_ID) REFERENCES myobj
(ID) ON DELETE CASCADE)
Kindly let me know if anything is wrong here.
The problem is that you're trying to point to row in myobj with the id 0, which doesn't exist. The default for that column should be null.
I'm quite sure that if you run select * from myobj where id = 0, you won't get any results back.
I'm using Netbeans to create entity class from database, I select all table in my database and the classes are created without any information about relations, like #OneToMany, #ManyToOne etc...
This is an example of two tables I have in my DB, is there anything else I need to specify in the tables creation?
CREATE TABLE `Indicator` (
`ID` int(11) NOT NULL,
`Number` int(11) NOT NULL,
`ApplicablePeriodTypeID` int(11) NOT NULL,
`IndicatorSourceID` int(11) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `IndicatorSourceID` (`IndicatorSourceID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1$$
CREATE TABLE `IndicatorSource` (
`ID` int(11) NOT NULL,
`CollectionName` varchar(255) NOT NULL,
`URL` varchar(1000) DEFAULT NULL,
`Number` int(11) NOT NULL,
`SourceName` varchar(255) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1$$
You might need to add a foreign key constraint, e.g. on IndicatorSourceID. Otherwise there's no hint that IndicatorSourceID refers to IndicatorSource.ID.
Changing the ENGINE to InnoDB and adding the foreign keys solved the problem. some db engine different from InnoDB dont support foreign key and when trying to add one, it doesn't generate any error.
As a side note: It seems the create entity classes from database feature in Netbeans 6.9 doesn't add relationships for foreign keys migrated from alternate keys -- only those migrated from primary keys.
Which database are you using?? Are you sure you have configure the database connection using
compatible driver to your database and jdk version...