diff --git a/guides/databases/cdl-to-ddl.md b/guides/databases/cdl-to-ddl.md index b48ef4f7a..2c3f186e1 100644 --- a/guides/databases/cdl-to-ddl.md +++ b/guides/databases/cdl-to-ddl.md @@ -611,7 +611,40 @@ CREATE TABLE Books ( ... ::: > [!tip] Consider using @assert.target instead -> Database constraints are meant to protect against data corruption due to programming errors. Prefer using the [`@assert.target`](../services/constraints#assert-target) for application-level input validation, which is more tuned for typical application scenarios, with error messages taylored for end users. +> Database constraints are meant to protect against data corruption due to programming errors. Prefer using the [`@assert.target`](../services/constraints#assert-target) for application-level input validation, which is more tuned for typical application scenarios, with error messages tailored for end users. + +#### `ON DELETE CASCADE` + +Think of the example above: a book can still exist, even if its author is deleted. However, this differs for existential relationships like the one between a book and its pages: a page cannot exist without a corresponding book. In such cases, you want the pages to be automatically deleted when the book (parent) is deleted. + +Typically such existential relationships are modeled in CDS using [compositions](../../cds/cdl#compositions). +That is why for managed **backlink** associations (those used in a composition's on-condition via `$self = .`), the foreign key constraints are generated with `ON DELETE CASCADE` by default, instead of `ON DELETE RESTRICT`: + +::: code-group +```cds [CDS Source] +entity Books { + key ID : Integer; + pages: Composition of many Pages on pages.book = $self; +} +entity Pages { + key number: Integer; + key book: Association to Books; // → ON DELETE CASCADE +} +``` +::: + +::: code-group +```sql [=> Generated DDL] +… +ALTER TABLE Pages ADD CONSTRAINT c__Pages_book + FOREIGN KEY(book_ID) REFERENCES Books(ID) + ON UPDATE RESTRICT + ON DELETE CASCADE + VALIDATED + ENFORCED + INITIALLY DEFERRED; +``` +::: #### Skipping with `@assert.integrity:false`