I have two tables :
CREATE TABLE IF NOT EXISTS `DB`.`global_history` (
`ID` INT(11) AUTO_INCREMENT,
`ID_HISTORY` INT(11) NULL,
PRIMARY KEY (`ID`),
CONSTRAINT `FK_HISTORY_GLOBAL_HISTORY`
FOREIGN KEY (`ID_HISTORY`)
REFERENCES `DB`.`history` (`ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION);
Second table :
CREATE TABLE IF NOT EXISTS `DB`.`history` (
`ID` INT(11) AUTO_INCREMENT,
`TIMESTAMP` DATETIME NOT NULL,
PRIMARY KEY (`ID`));
but when I try to delete a row in History (Second table) I get this error :
--> Cannot delete or update a parent row : a foreign key constraint fails
And I want the relationship to be #ManyToOne So when I remove a row from global_history it will not remove any row from history
And this is my model class :
Global history :
#ManyToOne
#JoinColumn(name = "ID_HISTORY", nullable = true)
private History history;
--> history is a simple class
when you define a F.K from a child (global_history) to parent (History table), child table can not has invalid F.K. so you should decide for deleting parent which cause F.K will be invalid.
a foreign key with cascade delete means that if a record in the parent table is deleted, then the corresponding records in the child table will automatically be deleted. This is called a cascade delete in SQL Server.
so if you want to prevent deleting corresponding child rows , you can set null value or default value by using following command:
ON DELETE SET NULL
ON DELETE SET DEFAULT
this is complete format:
CREATE TABLE child_table
(
column1 datatype [ NULL | NOT NULL ],
column2 datatype [ NULL | NOT NULL ],
...
CONSTRAINT fk_name
FOREIGN KEY (child_col1, child_col2, ... child_col_n)
REFERENCES parent_table (parent_col1, parent_col2, ... parent_col_n)
ON DELETE CASCADE
[ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ]
)
https://www.techonthenet.com/sql_server/foreign_keys/foreign_delete.php
Related
I have a table of Orders, and a table of Order Status Updates that points to order.id. I need to get a list of Orders, but I need to join in order status updates because I don't want orders which last status is 'Cancelled'
CREATE TABLE `orders` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`end_customer_id` bigint(20) NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `FK_end_customer` (`end_customer_id`),
CONSTRAINT `orders_ibfk_3` FOREIGN KEY (`end_customer_id`) REFERENCES `end_customers` (`id`) ON UPDATE CASCADE,
) ENGINE=InnoDB AUTO_INCREMENT=100333 DEFAULT CHARSET=utf8;
CREATE TABLE `order_status_updates` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`status` varchar(255) NOT NULL,
`date` datetime NOT NULL,
`order_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_order` (`order_id`),
CONSTRAINT `order_status_updates_ibfk_3` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
) ENGINE=InnoDB AUTO_INCREMENT=344180 DEFAULT CHARSET=utf8;
Current Criteria is:
final Criteria c = criteria("o")
.add(eq("o.endCustomer.id", endCustomerId));
return list(c.addOrder(desc("createdAt")));
I need to filter out Orders which latest status (sorted by Date) is Cancelled
Assuming a class called MyOrder and an ORDER_STATUS enum as well as id, status and createdAt field definitions:
final Criteria c = sessionFactory.getCurrentSession().createCriteria(MyOrder.class);
c.add(Restrictions.eq("id", yourId))
.add(Restrictions.ne("status", ORDER_STATUS.CANCELLED)
.addOrder(Order.desc("createdAt"));
I have a class with map inside. It is mapped with use of join table.
#Entity
#Table(name = "Sources")
#Lazy(false)
public class Sources {
#ManyToMany( fetch = FetchType.EAGER )
#JoinTable( name = "sources_lists", joinColumns = #JoinColumn( name = "list_id" ) )
#MapKeyColumn( name = "source_id" )
public Map<Integer, Source> getSources() { return sources; }
public void setSources( Map<Integer, Source> sourcesList ) { this.adSources = adSourcesList; }
private Map<Integer, Source> sources;
#Override
#Id #GeneratedValue(strategy = GenerationType.AUTO)
#Column( name="id", unique = true, nullable = false, updatable = false )
public Integer getId() { return super.getId(); }
}
I receive the following exception: "Unknown column 'sources0_.sources' in 'field list'".
When I change 'list_id' column name to the 'sources' things work, but I can't do this in production.
Tables are:
CREATE TABLE `sources` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`) );
CREATE TABLE `source` (
`DTYPE` varchar(31) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`className` varchar(255) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`));
CREATE TABLE `sources_lists` (
list_id` int(11) NOT NULL,
`source_id` int(11) NOT NULL,
KEY `FK54DCBD0B4307D0FC` (`source_id`),
KEY `FK54DCBD0B575FBECF` (`list_id`),
CONSTRAINT `FK54DCBD0B4307D0FC` FOREIGN KEY (`source_id`) REFERENCES `source` (`id`),
CONSTRAINT `FK54DCBD0B575FBECF` FOREIGN KEY (`list_id`) REFERENCES `sources` (`id`));
I realized that the issue was not with column, but with somethings else: I want to map Source objects by its id and Hibernate assumes that there are 3 columns in join table: parent object id (Sources class, list_id column), object id (Source class, source_id column) and a separate column for map key. I'll open other question to ask what is the way to map object in Hibernate by its id.
I've got tables Artist, Concert, and Artist_Concert, which contains many-to many connections between Artist and Concert.
The problem is: after adding a Concert with few Artists, when trying to delete rows from Artist_Concert, it only deletes only one row and nothing happens when trying to delete any others.
This is how I'm trying to delete rows in Java:
stat = connect.createStatement();
res = stat.executeQuery ("SELECT idConcert FROM concerthall.concert where ConcertName = '"+conc+"';");
res.first();
int idconc = res.getInt(1);
stat.execute ("DELETE FROM concerthall.artist_concert WHERE idConc="+idconc+"");
Artist
CREATE TABLE IF NOT EXISTS `concerthall`.`Artist` (
`idArtist` INT NOT NULL AUTO_INCREMENT,
`ArtName` VARCHAR(45) NOT NULL,
`ArtFee` INT NULL,
PRIMARY KEY (`idArtist`))
ENGINE = InnoDB
Artist-Concert
CREATE TABLE IF NOT EXISTS `concerthall`.`Artist_Concert` (
`idCA` INT NOT NULL AUTO_INCREMENT,
`idArt` INT NOT NULL,
`IdConc` INT NOT NULL,
INDEX `idart_idx` (`idArt` ASC),
INDEX `idconc_idx` (`IdConc` ASC),
PRIMARY KEY (`idCA`),
CONSTRAINT `idart2`
FOREIGN KEY (`idArt`)
REFERENCES `concerthall`.`Artist` (`idArtist`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `idconct4`
FOREIGN KEY (`IdConc`)
REFERENCES `concerthall`.`Concert` (`idConcert`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
Concert
CREATE TABLE IF NOT EXISTS `concerthall`.`Concert` (
`idConcert` INT NOT NULL AUTO_INCREMENT,
`ConcertName` VARCHAR(45) NOT NULL,
`ConcertDateTime` DATETIME NOT NULL,
`Organizator` INT NOT NULL,
PRIMARY KEY (`idConcert`),
INDEX `concertorg_idx` (`Organizator` ASC),
CONSTRAINT `concertorg`
FOREIGN KEY (`Organizator`)
REFERENCES `concerthall`.`Organizator` (`idOrganizator`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
The easiest way to drop duplicates is:
ALTER IGNORE TABLE table ADD UNIQUE INDEX( a, b );
In the INDEX() part, enter the name(s) of the column(s) you only want unique entries for. I think you want:
ALTER IGNORE TABLE concerthall.artist_concert ADD UNIQUE INDEX( idConc );
Then drop the index.
I have a parent and child table.
schema: parent(int id,varchar desc), child(int id, varchar desc, int parent_id(foreignKey)).
From this I created entities and then JPAControllers from those entities using netbeans.
When I tried to store a parent with a collection of child it throws java.lang.IllegalArgumentException: An instance of a null PK has been incorrectly provided for this find operation.. After inspecting the JPA controllers generated by netbeans, I found out that they are assuming that the child objects in the parent have an ID and in my case since the child objects are also new I don't have an ID for them. But what I don't understand is that why the following code is present in the netbeans generated JPAController code.
Collection<Child> attachedChildCollection = new ArrayList<Child>();
for (Child childCollectionChildToAttach : parent.getChildCollection()) {
childCollectionChildToAttach = em.getReference(childCollectionChildToAttach.getClass(), childCollectionChildToAttach.getId());
attachedChildCollection.add(childCollectionChildToAttach);
}
parent.setChildCollection(attachedChildCollection);
Does anybody know any way to solve this other than manually editing JPAControllers.
Below code snippet shows how I tried to store parent.
Parent parentObj = new Parent();
parentObj.setDesc("parent");
Collection<Child> childCollection = new ArrayList<>();
Child childObj = new Child();
childObj.setDesc("child1");
childCollection.add(childObj);
Child childObj2 = new Child();
childCollection.add("childObj2");
parentObj.setChildCollection(childCollection);
parentJpaController.create(parentObj);
script for creating tables given below
SET #OLD_UNIQUE_CHECKS=##UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET #OLD_SQL_MODE=##SQL_MODE, SQL_MODE='TRADITIONAL';
CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ;
USE `mydb` ;
-- -----------------------------------------------------
-- Table `mydb`.`PARENT`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`PARENT` (
`ID` INT NOT NULL AUTO_INCREMENT ,
`DESC` VARCHAR(45) NULL ,
PRIMARY KEY (`ID`) )
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`CHILD`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`CHILD` (
`ID` INT NOT NULL AUTO_INCREMENT ,
`DESC` VARCHAR(45) NULL ,
`PARENT` INT NOT NULL ,
PRIMARY KEY (`ID`) ,
INDEX `FK_CHILD_PARENT` (`PARENT` ASC) ,
CONSTRAINT `FK_CHILD_PARENT`
FOREIGN KEY (`PARENT` )
REFERENCES `mydb`.`PARENT` (`ID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
SET SQL_MODE=#OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=#OLD_UNIQUE_CHECKS;
Hi I'm trying to get the foreig key for a given table, I'm using this code :
ResultSet rs = meta.getImportedKeys(_con.getCatalog(), null, _tableName);
while (rs.next())
{
//get the foreignKeys
}
ResultSet rs2 = meta.getExportedKeys(_con.getCatalog(), null, _tableName);
while (rs2.next())
{
//get the foreignKeys
}
The resultSet is empty, although the table contains a foreign key and is a foreign key to another table,
the getImportedKeys works fine.
Thanks for any suggestions.
Tables :
CREATE TABLE `COMMANDE` (
`COMMANDE_ID` int(11) NOT NULL,
`CLIENT_ID` int(100) DEFAULT NULL,
`TOURNEE_ID` int(100) DEFAULT NULL,
PRIMARY KEY (`COMMANDE_ID`),
KEY `CLIENT_ID` (`CLIENT_ID`),
KEY `TOURNEE_ID` (`TOURNEE_ID`),
CONSTRAINT `commande_ibfk_1` FOREIGN KEY (`CLIENT_ID`) REFERENCES `CLIENT` (`CLIENT_ID`),
CONSTRAINT `commande_ibfk_2` FOREIGN KEY (`TOURNEE_ID`) REFERENCES `TOURNEE` (`TOURNEE_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `CLIENT` (
`CLIENT_ID` int(100) NOT NULL,
`LIBELLE` varchar(100) DEFAULT NULL,
PRIMARY KEY (`CLIENT_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I tried the code with both tables.
I think the problem is from the rather curious naming of the methods in JDBC, and the hard to grok description.
To get primary keys of a table, you should use getPrimaryKeys(), to get the foreign key of a table (and the primary key they reference), use getImportedKeys()
There are additional methods
- getExportedKeys() exposes the foreign keys that reference the specified table (so the table parameter specifies the table with the primary key)
- getCrossReference() is a combination of all of the above: you need to specify the tables on both sides of the constraint