I am working on a project with Java, Spring Boot, JPA and H2 database.
However, I am confused with how the database tables have been designed.
There are 3 tables A,B and C.
Table A has Table B's primary key as foreign key.
Table B has Table C's primary key as foreign key.
Table C has Table A's primary key as foreign key.
Since each table is dependent on other tables, when I am creating the schema of all the three I am getting an error indicating Table B is not found
I have even tried using ALTER commands but still facing the same issue.
Here is my code
DROP TABLE IF EXISTS TEAMS;
CREATE TABLE IF NOT EXISTS TEAMS (
`team_id` int (11) NOT NULL AUTO_INCREMENT,
`name` varchar (100) NOT NULL DEFAULT '0',
`train_id` int (11) NOT NULL DEFAULT '0',
PRIMARY KEY (`team_id`),
CONSTRAINT `FK_teams_trains` FOREIGN KEY (`train_id`) REFERENCES TRAINS (`train_id`)
);
DROP TABLE IF EXISTS USERS;
CREATE TABLE IF NOT EXISTS USERS (
`user_id` int (11) NOT NULL AUTO_INCREMENT,
`team_id` int (11) DEFAULT NULL,
`reports_to` int (11) DEFAULT NULL,
PRIMARY KEY (`user_id`),
CONSTRAINT `FK_users_teams` FOREIGN KEY (`team_id`) REFERENCES TEAMS (`team_id`),
CONSTRAINT `FK_users_users` FOREIGN KEY (`reports_to`) REFERENCES USERS (`user_id`)
);
DROP TABLE IF EXISTS TRAINS;
CREATE TABLE IF NOT EXISTS TRAINS` (
train_id INT (11) NOT NULL AUTO_INCREMENT,
train_name varchar (100) NOT NULL DEFAULT '0',
team_coach INT (11) NOT NULL DEFAULT '0',
train_vp INT (11) NOT NULL DEFAULT '0',
PRIMARY KEY (`train_id`)
);
ALTER TABLE TRAINS ADD CONSTRAINT `FK_trains_users` FOREIGN KEY (`team_coach`) REFERENCES USERS (`user_id`);
ALTER TABLE TRAINS ADD CONSTRAINT `FK_trains_users_2` FOREIGN KEY (`train_vp`) REFERENCES USERS (`user_id`);
ALTER TABLE TEAMS ADD CONSTRAINT `FK_teams_trains` FOREIGN KEY (`train_id`) REFERENCES TRAINS (`train_id`);
ALTER TABLE USERS ADD CONSTRAINT `FK_users_teams` FOREIGN KEY (`team_id`) REFERENCES TEAMS (`team_id`);
ALTER TABLE USERS ADD CONSTRAINT `FK_users_users` FOREIGN KEY (`reports_to`) REFERENCES USERS (`user_id`);
How can I solve this issue?
Related
I want to CREATE 4 tables that has FOREIGN KEYS of each other.
table students :
CREATE TABLE students
(
PRIMARY KEY (student_id),
student_id SERIAL,
student_name VARCHAR(100),
student_age INT,
entry_year INT,
graduate_year INT,
faculty_name VARCHAR(100),
group_id INT,
FOREIGN KEY (group_id) REFERENCES groups(group_id)
);
table groups :
CREATE TABLE groups
(
PRIMARY KEY (group_id),
group_id SERIAL,
group_name VARCHAR(100),
student_id INT,
FOREIGN KEY (student_id) REFERENCES students(student_id)
);
table lessons :
CREATE TABLE lessons
(
PRIMARY KEY (lesson_id),
lesson_id SERIAL,
lesson_name VARCHAR(100),
class_number INT,
date TIMESTAMP,
teacher_id INT,
group_id INT,
FOREIGN KEY(teacher_id) REFERENCES teachers(teacher_id),
FOREIGN KEY (group_id) REFERENCES groups(group_id)
);
table teachers :
CREATE TABLE teachers
(
PRIMARY KEY (teacher_id),
teacher_id INT,
teacher_name VARCHAR(100),
position VARCHAR(100)
);
And when I run this query in Java application, I gain an error with creation table students :
nested exception is org.postgresql.util.PSQLException: ERROR: relation "groups" does not exist
I know why It exception throwed.
Because I am creating table students with foreign key from table groups which has not yet been created.
But I have no idea how to fix It. Thanks in advance for response!
CREATE TABLE students
(
PRIMARY KEY (student_id),
student_id SERIAL,
student_name VARCHAR(100),
student_age INT,
entry_year INT,
graduate_year INT,
faculty_name VARCHAR(100),
group_id INT,
CONSTRAINT fk_group
FOREIGN KEY(group_id)
REFERENCES groups(group_id)
);
https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-foreign-key/
Created two tables namely Address and Employee.With relationship employee has a n address. The DB script as below.
create table address(addressid int,city varchar(10),pincode varchar(10));
insert into address(addressid,city,pincode) values(201,'Hosur',635109);
create table employee(empid int , firstname varchar(20),lastname varchar(20),department varchar(10),emailAddress varchar(50),baseLocation varchar(20),address int,FOREIGN KEY (Address) REFERENCES Address(addressId));
But I get the following error while trying to create the employee table:
Error Code: 1822. Failed to add the foreign key constraint. Missing
index for constraint 'employee_ibfk_1' in the referenced table
'Address' 0.117 sec
You should probably add a primary key on addressid in the Address table, this will create the index needed. In your current script there is no guarantee that addressid will be unique, hence if there would be duplicates a foreign key could never determine which row to refer to.
create table address(addressId int primary key not null, city varchar(10), pincode varchar(10));
because foreign key references primary key.
you don't have primary key in table address.
like this,
create table address(addressid int primary key,city varchar(10),pincode varchar(10));
create table employee(empid int , firstname varchar(20),lastname varchar(20),department varchar(10),emailAddress varchar(50),baseLocation varchar(20),address int ,FOREIGN KEY (address) REFERENCES address(addressid));
insert into address(addressid,city,pincode) values(201,'Hosur',635109);
You need to add the primary key constraint in the address table, inorder to add foreign key references in employee table
try with the following code:
create table address(addressid int primary key not null,city varchar(10),pincode varchar(10));
insert into address(addressid,city,pincode) values(201,'Hosur',635109);
create table employee(empid int , firstname varchar(20),lastname varchar(20),department varchar(10),emailAddress varchar(50),baseLocation varchar(20),address int,FOREIGN KEY (address) REFERENCES address(addressid));
I have below tables:
create table TABLE1 ( id int(10) unsigned NOT NULL AUTO_INCREMENT, deptId int(11) NOT NULL, DeptName varchar(32) NOT NULL, PRIMARY KEY (id), KEY Dept (deptId, DeptName))
create table TABLE2 ( id int(10) unsigned NOT NULL AUTO_INCREMENT, empId int(11) NOT NULL, DeptName varchar(32) NOT NULL, PRIMARY KEY (id), KEY DeptName (DeptName), CONSTRAINT T2FK FOREIGN KEY (DeptName) REFERENCES TABLE1 (DeptName))
TABLE1 has a MUL key defined with both dept id and dept name.
TABLE2 has a Foreign key which references only Dept name from TABLE1
The DTO for TABLE2 gets created like below:
#org.hibernate.annotations.NotFound(action = org.hibernate.annotations.NotFoundAction.IGNORE)
#javax.persistence.ManyToOne(targetEntity = org.amru.persistence.dto.TABLE1DTOImpl.class, fetch=javax.persistence.FetchType.EAGER)
#javax.persistence.JoinColumn(name = "deptName")
public org.amru.persistence.dto.TABLE1DTO getTABLE1() {
return TABLE1;
}
When I try to insert a row in TABLE2, it fails with foreign key constraint violation exception.
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`amru`.`TABLE2`, CONSTRAINT `T2FK` FOREIGN KEY (`DeptName`) REFERENCES `TABLE1` (`DeptName`))
I also see a EntityExistsException when I debug
What is possibly wrong? Is it recommended to refer a part of MUL key as foreign key in another table?
I am using jpa, hibernate, jboss, ejb and mysql
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Cannot add or update a child row: a foreign key constraint fails
What is possibly wrong?
This is very clear that, DeptName is foreign key in TABLE2, which is referring from TABLE1. So, you are not allowed to change the value in parent table as the data is being referenced in other table.
If you are supposed to do this, then you need to alter your table to apply cascade changes to child table as well for your Foreign Key
FOREIGN KEY (DeptName) REFERENCES TABLE1 (DeptName) ON DELETE CASCADE ON UPDATE CASCADE
I have a strange case:
It works:
rename table `test` to `test3`
but this does not work:
rename table `test` to `test1`
Error on rename of (errno: 150 - Foreign key constraint is incorrectly
formed)
UPDATE:
I set:
SET FOREIGN_KEY_CHECKS=0;
I do not have Foreign Keys
CREATE TABLE `test` ( `agglomeration_id` int(11) NOT NULL, `carpark_id` int(11) NOT NULL, `numer_urzadzenia` char(3) NOT NULL,
`payments_zone` char(1) DEFAULT NULL, `status` tinyint(1) DEFAULT NULL, `time_stamp` bigint(20) DEFAULT NULL,
`resource_uri` char(200) DEFAULT NULL, `test` int(1) NOT NULL, PRIMARY KEY (`test`) )
ENGINE=InnoDB DEFAULT CHARSET=utf8
You added a foreign key to an column of the test table, so that means that you need to drop the constraints before you rename it, or maybe deactivate the foreign key constraints and after that rename it.
for MySQL try :
SET FOREIGN_KEY_CHECKS=0; --> Temporary disables foreign key constraints
for SQL try:
EXEC sp_MSforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all" --> Disable foreign key constraints
Here is my tables definition
CREATE TABLE IF NOT EXISTS `store` (
`store_id` INT NOT NULL AUTO_INCREMENT,
`store_name` VARCHAR(1024) NOT NULL,
`store_user` INT NOT NULL,
`store_address` INT NOT NULL,
`store_type` INT NOT NULL,
`created_date` DATETIME NOT NULL,
`updated_date` DATETIME NOT NULL,
PRIMARY KEY (`store_id`)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `store_address` (
`address_id` INT NOT NULL AUTO_INCREMENT,
`address_line_1` VARCHAR(1024) NOT NULL,
`address_line_2` VARCHAR(1024) NOT NULL,
`address_line_3` VARCHAR(1024) NULL,
`city` VARCHAR(45) NOT NULL,
`locality` VARCHAR(100) NOT NULL,
`pincode` CHAR(6) NOT NULL,
`latitude` DECIMAL(8,6) NULL,
`longitude` DECIMAL(9,6) NULL,
`state` VARCHAR(45) NOT NULL,
`created_date` DATETIME NOT NULL,
`updated_date` DATETIME NOT NULL,
PRIMARY KEY (`address_id`),
CONSTRAINT `FK_STR_STR_ADR`
FOREIGN KEY (`address_id`)
REFERENCES `store` (`store_address`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
I am trying to have a 1-1 mapping between store and its address. Considering the DDL is ok, while generating JPA entities Store.java look like this:
#Entity
#Table(name="store")
public class Store
{
#Basic
#Column(name="created_date", nullable=false)
private Date createdDate;
#OneToOne(fetch=FetchType.LAZY, mappedBy="store", cascade=CascadeType.MERGE)
private StoreAddress storeAddress;
#Basic
#Column(name="store_address", columnDefinition="INT")
private int storeAddress2;
/////
Why is there a field storeAddress2 in Store.java? I think this is failing my insertion of a store. Any help?
Considering the DDL is ok [...]
The DDL is not OK, it is erroneous. As the tables are presently structured, the foreign key constraint is backward. store_address.address_id is the referenced key; the constrained column -- that is, the foreign key column -- should be store.store_address.
Moreover, be aware that putting the address into its own table and establishing a NOT NULL foreign key referencing it means that every store must have an address recorded, yet a store address does not have to correspond to any store. If you want the address to be optional then make store.store_address nullable, though that still permits addresses to exist that do not correspond to a store.
Alternatively, even though JPA prefers a forward mapping from parent to child such as you have presented, it is possible to map it in the other direction, so that store addresses cannot exist in the DB without a corresponding store, but stores do not have to have addresses recorded. In the DDL, that would correspond to deleting store.store_address, and creating store_address.store_id as a foreign key referencing store.store_id.
Update:
Here is some DDL to clarify my comments about the FK constraint. This is how an FK relationship between store and store_address should be written, given the column definitions as presented in the question:
CREATE TABLE IF NOT EXISTS `store` (
`store_id` INT NOT NULL AUTO_INCREMENT,
`store_address` INT NOT NULL,
-- ...
PRIMARY KEY (`store_id`),
CONSTRAINT `FK_STR_STR_ADR`
FOREIGN KEY (`store_address`)
REFERENCES `store_address` (`address_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION
)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `store_address` (
`address_id` INT NOT NULL AUTO_INCREMENT,
-- ...
PRIMARY KEY (`address_id`)
-- the FK constraint does NOT go here
)
ENGINE = InnoDB;
Note also that as I already wrote, this does not enforce a 1-1 relationship in the DB. If you want that then you could put a UNIQUE constraint on store.store_address, but it might be better to instead link the PKs of store and store_address. That way you can also prevent orphan store_address rows from being allowed. That could look like this:
CREATE TABLE IF NOT EXISTS `store` (
`store_id` INT NOT NULL AUTO_INCREMENT,
-- ... no store_address ...
PRIMARY KEY (`store_id`)
-- ... no FK constraint here ...
)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `store_address` (
-- addresses do not have independent IDs:
`store_id` INT NOT NULL,
-- ...
PRIMARY KEY (`store_id`),
CONSTRAINT `FK_STR_STR_ADR`
FOREIGN KEY (`store_id`)
REFERENCES `store` (`store_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION
)
ENGINE = InnoDB;
That does permit a store to exist without a corresponding address, which may be sensible, even though you say you don't want that.
Really, though, if a store must not exist without exactly one corresponding address, and a store address must not exist without a store, then why are you mapping these as separate tables? It gains you nothing except, maybe, less manual adjustment to automatically-generated entity classes. It's definitely a loss in the performance and DB complexity arenas.
Note, too, that JPA has annotations for mapping two closely-associated entities to the same table, if you insist that the addresses should be separate entities from their associated stores. Look into the #Embeddable and related annotations.