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...
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.
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?
There are two tables:
CREATE TABLE A(
id INT NOT NULL AUTO_INCREMENT,
softwareId VARCHAR(50) NOT NULL,
version VARCHAR(50) NOT NULL,
releaseDate TIMESTAMP NOT NULL,
PRIMARY KEY (id)
);
and
CREATE TABLE UPDATE_FILE(
id INT NOT NULL AUTO_INCREMENT,
updateId INT,
FOREIGN KEY (updateId) REFERENCES SOFTWARE_UPDATE(id) ON DELETE CASCADE ON UPDATE CASCADE,
osName VARCHAR(50) NOT NULL,
osArch VARCHAR(50) NOT NULL,
filePath VARCHAR(2048) NOT NULL,
fileName VARCHAR(50) NOT NULL,
PRIMARY KEY (id)
);
they have relationship on updateId.
I know how to add data into a table with no relationships.
getConnection().prepareStatement("INSERT INTO table(c1,c2,c3) VALUES(?,?,?)");
pStatement.setString(1, version);
pStatement.setString(2, path);
pStatement.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
pStatement.executeUpdate();
I'm not sure if adding new data into tables with relationship is the same?
It is the same. But may I suggest you use JPA instead of JDBC for this? I think that will be really easy when it comes to complex foreign key mappings. Make sure the database you are using is JPA compatible though.
I was working with UIs where the user will click the add button to add employees, but when I do it, it gives me an error like this
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`finalpayroll`.`personal_info`, CONSTRAINT `personal_info_ibfk_1`
How would I fix this?? I know I am using a parent key, and its foreign key is the User, and also take note that the parent key has already a data, but it seems my query won't work, why is that? I am using a foreign key with delete cascade and on update cascade so that when I delete a data, all of the child table rows will be deleted, vice versa. here's my key for adding or inserting statements
public void addEmployee(Personal p ,Contact c,Employee e) {
Connection conn = Jdbc.dbConn();
Statement statement = null;
String insert1 = "INSERT INTO personal_info (`First_Name`, `Middle_Initial`, `Last_Name`, `Date_Of_Birth`, `Marital_Status`, `Beneficiaries`) VALUES ('"+p.getFirstName()+"', '"+p.getMiddleInitial()+"'" +
" , '"+p.getLastName()+"', '"+p.getDateOfBirth()+"', '"+p.getMaritalStatus()+"', '"+p.getBeneficiaries()+"')";
try {
statement = conn.createStatement();
statement.executeUpdate(insert1);
statement.close();
conn.close();
JOptionPane.showMessageDialog(null, "Employee Added!!");
} catch(Exception ex) {
ex.printStackTrace();
}
}
Users table:
CREATE TABLE `users` (
`idusers` int(11) NOT NULL AUTO_INCREMENT,
`emp_id` varchar(45) DEFAULT NULL,
`emp_pass` varchar(45) DEFAULT NULL,
PRIMARY KEY (`idusers`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
Personal_info table:
CREATE TABLE `personal_info` (
`idpersonal_info` int(11) NOT NULL AUTO_INCREMENT,
`First_Name` varchar(45) DEFAULT NULL,
`Middle_Initial` varchar(45) DEFAULT NULL,
`Last_Name` varchar(45) DEFAULT NULL,
`Date_Of_Birth` varchar(45) DEFAULT NULL,
`Marital_Status` varchar(45) DEFAULT NULL,
`Beneficiaries` varchar(45) DEFAULT NULL,
PRIMARY KEY (`idpersonal_info`),
CONSTRAINT `personal_info_ibfk_1`
FOREIGN KEY (`idpersonal_info`)
REFERENCES `users` (`idusers`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
You are trying to insert a record with 6 fields: First_Name, Middle_Initial, Last_Name, Date_Of_Birth, Marital_Status and Beneficiaries. Your schema is currently unknown but none of these fields seem to be a candidate foreign key to id of User table you mentioned. Thus I think there is a default value for that foreign key column and that default value is missing in User table.
Needless to say, you shouldn't have a default value for a foreign key of any table..
I am adding these information regarding your questions in comments and update on your question:
A foreign key is a link between a child table and parent table, personal_info and users tables in your case respectively. Child table's foreign key column must reference to a key value in parent table which means that for every value in child table's FK column, there must be a value in parent table's linked column.
Now, in your case when you try to insert a new personal_info record MySQL assigns a idpersonal_info to it, since you defined it as auto increment. But since there is a link to users table, MySQL searchs for the new idpersonal_info to be inserted in users table's idusers column. And as you are getting this exception, you surely don't have that value in the users table.
You can change your table structure as follows:
CREATE TABLE `personal_info` (
`idpersonal_info` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
... OTHER FIELD DEFINITIONS,
PRIMARY KEY (`idpersonal_info`),
CONSTRAINT `user_id_fk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`idusers`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB
And your query will need to include user_id field as well. So it will be something like this:
INSERT INTO personal_info
(`user_id`, `First_Name`, `Middle_Initial`, `Last_Name`, `Date_Of_Birth`, `Marital_Status`, `Beneficiaries`)
VALUES ( .... SET YOUR VALUES HERE. DON'T FORGET TO SET A VALID USER_ID
Looks like in your Personal_Info table you have a column called "finalpayroll", that points to a column in another table (a foreign key) and it's required (not nullable). In your insert you're not giving it a value. So what you could do is make that column nullable.
Or could be the other way around as #Konstantin Naryshkin is saying
What the error means is that you are trying to insert a value into a column with a foreign key a value that is not in the remote table.
I assume that there is a user column that we are not seeing. Since you are not explicitly setting the value, I assume that it is getting a default. The default value is not in the parent table.
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.