Why aren't my foreign keys working? - java

My create table statement:
CREATE TABLE main_table (
_ID INTEGER PRIMARY KEY AUTOINCREMENT,
account_id INTEGER NOT NULL,
employee_id INTEGER NOT NULL,
rating REAL NOT NULL,
timestamp LONG NOT NULL,
FOREIGN KEY(account_id) REFERENCES ACCOUNTS(_ID),
FOREIGN KEY(employee_id) REFERENCES EMPLOYEES(_ID),
UNIQUE (account_id, employee_id, timestamp));
However now if I do something like
public void deleteAccount(long accountId) {
mDatabase.delete(
ACCOUNTS,
_ID + " = ?",
new String[]{accountId + ""}
);
}
Which is basically DELETE FROM ACCOUNTS WHERE _ID = some_id but it isn't cascading through the other tables (employees or main_table) and deleting any records there that link up through the foreign keys.
I do have this code as well:
#Override
public void onConfigure(SQLiteDatabase db){
db.setForeignKeyConstraintsEnabled(true);
}
Am I misunderstanding how these work? Isn't this what foreign keys are for? Why isn't it cascading?

You have to mention explicitly if you want any cascading
Change the query like below
CREATE TABLE main_table (
_ID INTEGER PRIMARY KEY AUTOINCREMENT,
account_id INTEGER NOT NULL,
employee_id INTEGER NOT NULL,
rating REAL NOT NULL,
timestamp LONG NOT NULL,
FOREIGN KEY(account_id) REFERENCES ACCOUNTS(_ID) ON DELETE CASCADE,
FOREIGN KEY(employee_id) REFERENCES EMPLOYEES(_ID) ON DELETE CASCADE,
UNIQUE (account_id, employee_id, timestamp));

Related

Java Springboot JPA joining multiple tables

I'm new to Java Springboot and I want to join multiple tables.
I have this MySQL schema :
CREATE TABLE `users`
(
`id` int NOT NULL AUTO_INCREMENT,
`email` varchar(128) NOT NULL,
`nickname` varchar(128) NOT NULL,
`password` varchar(256) NOT NULL,CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
UNIQUE KEY `nickname` (`nickname`)
);
CREATE TABLE `organizations` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(128) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `org_abilities`
(
`id` int NOT NULL AUTO_INCREMENT,
`key` varchar(128) NOT NULL,
`description` varchar(128) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_key` (`key`) USING BTREE
);
CREATE TABLE `org_permissions`
(
`id` int NOT NULL AUTO_INCREMENT,
`id_user` int NOT NULL,
`id_organization` int NOT NULL,
`id_ability` int NOT NULL,
PRIMARY KEY (`id`),
KEY `id_organization` (`id_organization`),
KEY `id_user` (`id_user`),
KEY `users_permissions_ibfk_2` (`id_ability`),
CONSTRAINT `org_permissions_ibfk_0` FOREIGN KEY (`id_organization`) REFERENCES `organizations` (`id`),
CONSTRAINT `org_permissions_ibfk_1` FOREIGN KEY (`id_user`) REFERENCES `users` (`id`),
CONSTRAINT `org_permissions_ibfk_2` FOREIGN KEY (`id_ability`) REFERENCES `org_abilities` (`id`)
);
Where my table org_permissions represent all abilities that a user has within an organization.
I have created the corresponding Java classes. I have a JPA to fetch the datas from the DB to the classes.
I want in my Organization class to have a field Map<long, List<Pair<long, String>>> managers which map an id_user to a list of tuple of abilities where the tuple is (id_ability, org_ability.key).
Finally I use DTO to send my response, and I want my response to look like that :
{
id : _id_organization,
name : "organisation name",
managers : {
id_user: [(id_ability, key), (id_ability, key)],
id_user:[(id_ability, key), (id_ability, key)]
}
}
For example:
SELECT op.*, oa.* FROM org_permissions as op
JOIN org_abilities oa on oa.id = op.id_ability
JOIN organizations o on o.id = op.id_organization
JOIN users u on u.id = op.id_user;
Here, user with id 1 is member of organization 1 and 2. for organization 1 user 1 has the CREATE_EVENTS and DELETE_EVENTS abilities and for organization 2 he only have the DELETE_EVENTS ability.
When getting all the organization I want this result :
[{
id : 1,
name : "Org1",
managers : {
1: [(1, "CREATE_EVENT"), (2,"CREATE_EVENT")]
}
},
{
id : 2,
name : "Org2",
managers : {
1: [(2,"CREATE_EVENT")]
}
}]
Thanks for your help, I'm a bit lost with the High level of springboot and JPA
P.S.: I tried to ask to chat GPT but nothing was concluent

Why a SQL SELECT statement doesn't return COUNT() result on Java Spring boot project?

this is my first question here so, please ask if you need more information. I am working on a personal project. I have a relatively complex relational database structure. I create schema.sql on my spring boot project as well as data.sql with sample data. I try to create a web application for simulated fitness centre web pages. I try to display the location name and number of visits for the user. I create a userLocation bean for keeping the result set as a list of the select query. I can test the statement on H2 database and its work. However, on my code, I cannot get the number of visits from the select statement.
Here is my userlocation bean,
#Data
#NoArgsConstructor
public class UserLocation {
private String locName;
private int numOfVisit;
}
Controller class getMapping method
#GetMapping("/secure/userLocation")
public String myLocation(Model model, Authentication authentication) {
String email = authentication.getName();
User currentUser = da.findUserAccount(email);
model.addAttribute("myLocationList", da.getUserLocationList(currentUser.getUserId()));
return "/secure/userLocation";
}
Here database access method;
public List<UserLocation> getUserLocationList(Long userId) {
MapSqlParameterSource namedParameters = new MapSqlParameterSource();
String query = "SELECT l.locName, COUNT(ul.dayOfVisit) FROM location l "
+ "INNER JOIN userLocation ul ON l.locId = ul.locId "
+ "INNER JOIN sec_user sc ON ul.userId = sc.userId "
+ "WHERE sc.userId = :userId AND ul.locId = 1"
+ "GROUP BY l.locName";
namedParameters.addValue("userId", userId);
return jdbc.query(query, namedParameters, new BeanPropertyRowMapper<UserLocation>(UserLocation.class));
}
here schema.sql
CREATE TABLE location (
locId BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
locName VARCHAR(75),
locAddress VARCHAR(255),
locPhone VARCHAR(25),
locEmail VARCHAR(75)
);
CREATE TABLE sec_user (
userId BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(75),
lastName VARCHAR(75),
adress VARCHAR(255),
phone VARCHAR(10),
email VARCHAR(75) NOT NULL UNIQUE,
encryptedPassword VARCHAR(128) NOT NULL,
enabled BIT NOT NULL
);
CREATE TABLE coach (
coachId BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
coachName VARCHAR(75),
coachLevel BIGINT,
coachRating BIGINT,
aboutMe VARCHAR(255)
);
CREATE TABLE fitnessClass (
classId BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
className VARCHAR(75),
classPrice DOUBLE
);
CREATE TABLE generalCert (
certId BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
certName VARCHAR(75)
);
CREATE TABLE certCoach (
certId BIGINT NOT NULL,
coachId BIGINT NOT NULL
);
ALTER TABLE certCoach
ADD CONSTRAINT certCoach_FK1 FOREIGN KEY (certId)
REFERENCES generalCert (certId);
ALTER TABLE certCoach
ADD CONSTRAINT certCoach_FK2 FOREIGN KEY (coachId)
REFERENCES coach (coachId);
CREATE TABLE userLocation (
userLocId BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
locId BIGINT NOT NULL,
userId BIGINT NOT NULL,
isHomeLoc BIT,
dayOfVisit DATE
);
ALTER TABLE userLocation
ADD CONSTRAINT userLocation_FK1 FOREIGN KEY (locId)
REFERENCES location (locId);
ALTER TABLE userLocation
ADD CONSTRAINT userLocation_FK2 FOREIGN KEY (userId)
REFERENCES sec_user (userId);
CREATE TABLE amenity (
amenityId BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
amenityName VARCHAR(75),
locId BIGINT
);
ALTER TABLE amenity
ADD CONSTRAINT amenity_FK FOREIGN KEY (locId)
REFERENCES location (locId);
CREATE TABLE room (
roomId BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
roomName VARCHAR(75),
locId BIGINT
);
ALTER TABLE room
ADD CONSTRAINT room_FK FOREIGN KEY (locId)
REFERENCES location (locId);
CREATE TABLE classCoach (
classId BIGINT NOT NULL,
coachId BIGINT NOT NULL
);
ALTER TABLE classCoach
ADD CONSTRAINT classCoachFK1 FOREIGN KEY (classId)
REFERENCES fitnessClass(classId);
ALTER TABLE classCoach
ADD CONSTRAINT classCoachFK2 FOREIGN KEY (coachId)
REFERENCES coach(coachId);
CREATE TABLE schedule (
ScheduleId BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
ScheduleDate DATE,
ScheduleTime TIME,
RoomId BIGINT,
ClassId BIGINT NOT NULL,
LocId BIGINT NOT NULL
);
ALTER TABLE schedule
ADD CONSTRAINT scheduleFK1 FOREIGN KEY (roomId)
REFERENCES room(RoomId);
ALTER TABLE schedule
ADD CONSTRAINT scheduleFK2 FOREIGN KEY (classId)
REFERENCES fitnessClass(classId);
ALTER TABLE schedule
ADD CONSTRAINT ScheduleFK3 FOREIGN KEY (LocId)
REFERENCES location(LocId);
CREATE TABLE reservation (
ClassId BIGINT NOT NULL,
userId BIGINT NOT NULL
);
ALTER TABLE reservation
ADD CONSTRAINT reservationFK1 FOREIGN KEY (classId)
REFERENCES fitnessClass(classId);
ALTER TABLE reservation
ADD CONSTRAINT reservationFK2 FOREIGN KEY (userId)
REFERENCES sec_user(userId);
CREATE TABLE workFrom (
coachId BIGINT NOT NULL,
locId BIGINT NOT NULL
);
ALTER TABLE workFrom
ADD CONSTRAINT workFromFK1 FOREIGN KEY (coachId)
REFERENCES coach(coachId);
ALTER TABLE workFrom
ADD CONSTRAINT workFromFK2 FOREIGN KEY (locId)
REFERENCES location(locId);
CREATE TABLE review (
ReviewId BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
CoachId BIGINT NOT NULL,
userId BIGINT NOT NULL,
ReviewDate DATE,
ComScore CHAR(1),
EnthScore CHAR(1),
PunctScore CHAR(1),
ReviewText VARCHAR(500)
);
ALTER TABLE review
ADD CONSTRAINT reviewFK1 FOREIGN KEY (coachId)
REFERENCES coach(coachId);
ALTER TABLE review
ADD CONSTRAINT reviewFK2 FOREIGN KEY (userId)
REFERENCES sec_user(userId);
CREATE TABLE Reference (
CoachId BIGINT NOT NULL,
userId BIGINT NOT NULL
);
ALTER TABLE Reference
ADD CONSTRAINT ReferenceFK1 FOREIGN KEY (coachId)
REFERENCES coach(coachId);
ALTER TABLE review
ADD CONSTRAINT ReferenceFK2 FOREIGN KEY (userId)
REFERENCES sec_user(userId);
CREATE TABLE ClientCoach (
coachId BIGINT NOT NULL,
userId BIGINT NOT NULL,
myCoach BIT
);
ALTER TABLE ClientCoach
ADD CONSTRAINT ClientCoachFK1 FOREIGN KEY (coachId)
REFERENCES coach(coachId);
ALTER TABLE ClientCoach
ADD CONSTRAINT ClientCoachFK2 FOREIGN KEY (userId)
REFERENCES sec_user(userId);
CREATE TABLE sec_role(
roleId BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
roleName VARCHAR(30) NOT NULL UNIQUE
);
CREATE TABLE user_role
(
id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
userId BIGINT NOT NULL,
roleId BIGINT NOT NULL
);
ALTER TABLE user_role
ADD CONSTRAINT user_role_uk UNIQUE (userId, roleId);
ALTER TABLE user_role
ADD CONSTRAINT user_role_fk1 FOREIGN KEY (userId)
REFERENCES sec_user (userId);
ALTER TABLE user_role
ADD CONSTRAINT user_role_fk2 FOREIGN KEY (roleId)
REFERENCES sec_role (roleId);
Here the result web page
Here is EERD for the schema
Please try:
SELECT l.locName, COUNT(ul.dayOfVisit) AS numOfVisit -- ...
(to alias numOfVisit), since we are using a BeanPropertyRowMapper (which mapps by "bean properties" (i.e. "field names"): https://www.google.com/search?q=java+bean+naming+conventions).
Alternatively use an other/custom RowMapper.
And since even javadoc recommends:
... For best performance, consider using a custom RowMapper implementation.
Best:
return jdbc.query(query, namedParameters,
(ResultSet rs, int rowNum) -> { // one ResultSet per row:
// column indices start with 1(!):
return new UserLocation(rs.getString(1), rs.getInt(2));
// alternatively (name based): rs.getString("locName")...
}
);
;)
RowMapper javadoc (spring-jdbc:current)
ResultSet javadoc (jdk17)
and since RowMapper is a/meets the requirements of a functional interface, we can write it as lambda expression.

FOREIGN KEY ON UPDATE CASCADE, Syntax error: Encountered "CASCADE"

I have made a Users and Items table successfully using JDBC in NetBeans but executing the next two CREATE commands is giving errors.
[Exception, Error code 30,000, SQLState 42X01] Syntax error: Encountered "CASCADE" at line 10, column 19.
The same error for the Orders and Cart table.
CREATE TABLE Users(
FName VARCHAR(60),
LName VARCHAR(60),
Email VARCHAR(60),
UName VARCHAR(30) NOT NULL,
PWord VARCHAR(60),
PRIMARY KEY(UName)
);
CREATE TABLE Items(
INumber INT NOT NULL,
IName VARCHAR(80),
IPrice FLOAT,
QtyAvailable INT CHECK(QtyAvailable>=0),
IDescription VARCHAR(200),
PRIMARY KEY(INumber)
);
CREATE TABLE Cart(
CartID INT NOT NULL AUTO_INCREMENT,
Username VARCHAR(30) NOT NULL,
ItemNumber INT NOT NULL,
Qty INT,
PRIMARY KEY(CartID),
constraint userIDFK
FOREIGN KEY (Username) REFERENCES Users(UName)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT itemIDFK
FOREIGN KEY (ItemNumber) REFERENCES Items(INumber)
ON DELETE CASCADE
ON UPDATE CASCADE
);
CREATE TABLE Orders(
ONumber INT NOT NULL AUTO_INCREMENT,
ODate VARCHAR(20),
OUName VARCHAR(30) NOT NULL,
OItemNumber INT NOT NULL,
Qty INT,
UnitPrice FLOAT,
OComplete VARCHAR(3),
CardName VARCHAR(20),
CardNumer DOUBLE,
CSV INT,
ExpDate VARCHAR(11),
Email VARCHAR(60),
PRIMARY KEY(ONumber),
constraint ouserIDFK
FOREIGN KEY (OUName) REFERENCES Users(UName)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT oitemIDFK
FOREIGN KEY (OItemNumber) REFERENCES Items(INumber)
ON DELETE CASCADE
ON UPDATE CASCADE
);
I had looked for a solution and I had found this a bit relateable can someone please help me out with the code.
https://stackoverflow.com/a/30697331/6766368

Foreign key constraint is incorrectly formed - java-mysql

what is the mysql problem ??
I do not know what the error is since I had not used foreign keys before
String clientes = "CREATE TABLE clientes("+
"ID INTEGER NOT NULL AUTO_INCREMENT,"+
"CUENTA INTEGER,"+
"NOMBRE VARCHAR(255),"+
"EDAD INTEGER,"+
"ADICIONAL INTEGER,"+
"DOMICILIO VARCHAR(255),"+
"PRIMARY KEY(ID))";
String cuenta = "CREATE TABLE cuenta("+
"CUENTA INTEGER,"+
"SALDOAFAVOR DOUBLE(14,2),"+
"SALDOENCONTRA DOUBLE(14,2),"+
"FECHACORTE DATE,"+
"LIMITECREDITO DOUBLE(14,2),"+
"FOREIGN KEY(CUENTA) REFERENCES clientes(CUENTA))";
The correct reference and definition would use the primary key:
CREATE TABLE cuenta (
CUENTA INTEGER AUTO_INCREMENT PRIMARY KEY,
CLIENTE_ID INT,
SALDOAFAVOR NUMERIC(14, 2),
SALDOENCONTRA NUMERIC(14, 2),
FECHACORTE DATE,
LIMITECREDITO NUMERIC(14,2),
FOREIGN KEY(CLIENT_ID) REFERENCES clientes(ID)
);
Notes:
CUENTA seems like it should be the primary key of this table.
The foreign key reference should use the id on CLIENTES.
You don't need CUENTA on CLIENTES.
DOUBLE(14, 2) is not the right data type. You want DECIMAL(14, 2)/NUMERIC(14, 2).

MySQLIntegrityConstraintViolationException: Cannot add or update a child row

My view add.scala.html is this
So if i add a product it shows on same screen and i have a delete button to delete product.My problem is that when i add new product it works fine but when i add a new product after deleting any one then it gives me the error
[PersistenceException: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`shopdb`.`product_shop`, CONSTRAINT `fk_product_shop_product_01` FOREIGN KEY (`product_id`) REFERENCES `product` (`id`))]
on my models.Product.java
public static Product create(Product product,Shop shop) {
product.save();
static List<Product> products = new ArrayList<>();
products.add(product);
shop.products = products;
shop.save();//getting error on this line
return product;
}
public static void delete(Long id) {
find.ref(id).delete();
}
my database
create table product (
id bigint auto_increment not null,
name varchar(255),
price float,
category varchar(255),
constraint pk_product primary key (id))
;
create table shop (
id bigint auto_increment not null,
name varchar(255),
address_line1 varchar(255),
address_line2 varchar(255),
address_line3 varchar(255),
city varchar(255),
town varchar(255),
phone_number varchar(255),
category varchar(255),
shop_pic longblob,
owner_id bigint,
constraint pk_shop primary key (id))
;
create table product_shop (
product_id bigint not null,
shop_id bigint not null,
constraint pk_product_shop primary key (product_id, shop_id))
;
alter table product_shop add constraint fk_product_shop_product_01 foreign key (product_id) references product (id) on delete restrict on update restrict;
alter table product_shop add constraint fk_product_shop_shop_02 foreign key (shop_id) references shop (id) on delete restrict on update restrict;
Any help would be really appreciated.
Why are you assigning
shop.products = products;
shouldn't you do
shop.products.add(products); ?

Categories

Resources