From 9c8d82c64dbb537f47daffe2eb9b7ede77faf8ba Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Wed, 11 Jun 2025 18:16:20 +0200 Subject: [PATCH 01/31] Java: Write through Views --- java/working-with-cql/query-execution.md | 180 +++++++++++++---------- 1 file changed, 100 insertions(+), 80 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index af60b19a27..13e2d2f191 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -117,12 +117,12 @@ var params = Map.of("minStock", 100); Result result = service.run(query, params); ``` -#### Adding Query Hints for SAP HANA { #hana-hints} +### Query Hints { #hana-hints} To add a hint clause to a statement, use the `hints` method and prefix the [SAP HANA hints](https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4ba9edce1f2347a0b9fcda99879c17a1.htmlS) with `hdb.`: ```java -CqnSelect query = Select.from(BOOKS).hints("hdb.USE_HEX_PLAN", "hdb.ESTIMATION_SAMPLES(0)"); +Select.from(BOOKS).hints("hdb.USE_HEX_PLAN", "hdb.ESTIMATION_SAMPLES(0)"); ``` ::: warning Hints prefixed with `hdb.` are directly rendered into SQL for SAP HANA and therefore **must not** contain external input! @@ -160,7 +160,7 @@ If no rows are touched the execution is successful but the row count is 0. The setters of an [update with expressions](../working-with-cql/query-api#update-expressions) are evaluated on the database. The result of these expressions is not contained in the update result. ::: -### Working with Structured Documents +### Structured Documents It's possible to work with structured data as the insert, update, and delete operations cascade along *compositions*. @@ -223,45 +223,123 @@ CqnDelete delete = Delete.from("bookshop.Orders").matching(singletonMap("OrderNo long deleteCount = service.run(delete).rowCount(); ``` -### Resolvable Views and Projections { #updatable-views} +## Views and Projections { #views } -The CAP Java SDK aims to resolve statements on non-complex views and projections to their underlying entity. When delegating queries between Application Services and Remote Services, statements are resolved to the entity definitions of the targeted service. Using the Persistence Service, only modifying statements are resolved before executing database queries. This allows to execute [Insert](./query-api#insert), [Upsert](./query-api#upsert), [Update](./query-api#update), and [Delete](./query-api#delete) operations on database views. For [Select](./query-api#select) statements database views are always leveraged, if available. +The CDS compiler automatically generates [DDL](../../guides/databases?impl-variant=java#generating-sql-ddl) files from your CDS model, including database views for all CDS [views and projections](../../cds/cdl#views-projections). -Views and projections can be resolved if the following conditions are met: +These views are used to read data from the database, while write operations are resolved to the underlying entities, if possible. -- The view definition does not use any other clause than `columns` and `excluding`. +::: warning +Avoid using to-many associations on the select list of CDS views, as this prevents write operations and can lead to performance issues due to duplicating records on the DB. +::: + +### Runtime Views { #runtimeviews } + +To add or update CDS views without redeploying the database schema, annotate your views with [@cds.persistence.skip](../../guides/databases#cds-persistence-skip). This tells the CDS compiler to skip generating database views for these entities. Instead, the CAP Java runtime dynamically resolves these views at runtime. + +::: warning Limitations +Runtime views do not support complex views that use aggregations, unions, joins, or subqueries in the `FROM` clause. + +To read [draft-enabled](../fiori-drafts#reading-drafts) entities, set `cds.drafts.persistence` to `split`. +::: + +For example, consider the following CDS model and query: + +```cds +entity Books { + key id : UUID; + title : String; + stock : Integer; + author : Association to one Authors; +} +@cds.persistence.skip +entity BooksWithLowStock as projection on Books { + id, title, author.name as author +} where stock < 10; +``` +```sql +Select BooksWithLowStock where author = 'Kafka' +``` + +CAP Java provides two modes for resolving runtime views: + +**`cte` mode**: The runtime translates the view definition into a _Common Table Expression_ (CTE) and sends it with the query to the database. + +```sql +WITH BOOKSWITHLOWSTOCK_CTE AS ( + SELECT B.ID, + B.TITLE, + A.NAME AS "AUTHOR" + FROM BOOKS B + LEFT OUTER JOIN AUTHOR A ON B.AUTHOR_ID = A.ID + WHERE B.STOCK < 10 +) +SELECT ID, TITLE, AUTHOR AS "author" + FROM BOOKSWITHLOWSTOCK_CTE + WHERE A.NAME = ? +``` + +::: tip +In CAP Java 3.10, enable `cte` mode with **cds.sql.runtimeView.mode: cte** +::: + +**`resolve` mode**: The runtime _resolves_ the view definition to the underlying persistence entities and executes the query directly against them. + +```sql +SELECT B.ID, B.TITLE, A.NAME AS "author" + FROM BOOKS AS B + LEFT OUTER JOIN AUTHORS AS A ON B.AUTHOR_ID = A.ID + WHERE B.STOCK < 10 AND A.NAME = ? +``` + +::: warning Limitations of `resolve` mode +Expands to other runtime views and complex draft queries are not supported. +::: + + +### Write through Views { #updatable-views} + +To run [Insert](./query-api#insert), [Upsert](./query-api#upsert), [Update](./query-api#update), and [Delete](./query-api#delete) statements on CDS views, the CAP Java runtime resolves them to the underlying entity definitions, if possible - similar to the runtime view *resolve* mode for queries. + +When delegating queries between Application Services and Remote Services, statements are also resolved to the entity definitions of the targeted service. + +Views and projections can be resolved for write operations if the following conditions are met: + +- The view definition does not use any other clause than `columns` and `excluding` - `join`, `union` and `where` are not supported. - The projection includes all key elements; with the exception of insert operations with generated UUID keys. - The projection includes all elements with a `not null` constraint, unless they have a default value. -- The projection must not include calculated fields when running queries against a remote OData service. - The projection must not include [path expressions](../../cds/cql#path-expressions) using to-many associations. +- Projections targeting remote OData services must not include calculated elements. -For [Insert](./query-api#insert) or [Update](./query-api#update) operations, if the projection contains functions or expressions, these values are ignored. Path expressions navigating *to-one* associations, can be used in projections as shown by the `Header` view in the following example. The `Header` view includes the element `country` from the associated entity `Address`. +For [Insert](./query-api#insert) or [Update](./query-api#update) operations, if the projection contains functions or expressions, these values are ignored. + +Path expressions navigating *to-one* compositions, can be used in projections as shown by `headerStatus` in the following example, which includes the element `status` of the `OrderHeader` entity. ```cds -// Supported entity Order as projection on bookshop.Order; entity Order as projection on bookshop.Order { ID, status as state }; -entity Order as projection on bookshop.Order excluding { status }; -entity Header as projection on bookshop.OrderHeader { key ID, address.country as country }; + +entity Order as projection on bookshop.Order { + ID, + header.status as headerStatus, + header.customer.name as customerName @readonly +} excluding { status }; ``` -If a view is too complex to be resolved by the CDS runtime, the statement remains unmodified. Views that cannot be resolved by the CDS runtime include the use of `join`, `union` and the `where` clause. +::: warning Path Expressions using Associations are readonly +Path expressions navigating associations are by default [not writable](#cascading-over-associations) and need to be annotated with [@readonly](../../guides/providing-services#readonly). +::: + +Write operations on views that cannot be resolved by the CAP Java runtime remain unmodified - For the Persistence Service, this means the runtime _attempts_ to execute the write operation on the database view. Whether this execution is possible is [database dependent](../cqn-services/persistence-services#database-support). - For Application Services and Remote Services, the targeted service will reject the statement. -Example of a view that can't be resolved: - -```cds -// Unsupported -entity DeliveredOrders as select from bookshop.Order where status = 'delivered'; -entity Orders as select from bookshop.Order inner join bookshop.OrderHeader on Order.header.ID = OrderHeader.ID { Order.ID, Order.items, OrderHeader.status }; -``` ## Concurrency Control Concurrency control allows protecting your data against unexpected concurrent changes. -### Optimistic Concurrency Control {#optimistic} +### Optimistic Locking {#optimistic} Use _optimistic_ concurrency control to detect concurrent modification of data _across requests_. The implementation relies on an _ETag_, which changes whenever an entity instance is updated. Typically, the ETag value is stored in an element of the entity. @@ -400,64 +478,6 @@ The `lock()` method has an optional parameter `timeout` that indicates the maxim The parameter `mode` allows to specify whether an `EXCLUSIVE` or a `SHARED` lock should be set. -## Runtime Views { #runtimeviews } - -The CDS compiler generates [SQL DDL](../../guides/databases?impl-variant=java#generating-sql-ddl) statements from your CDS model, including SQL views for all CDS [views and projections](../../cds/cdl#views-projections). As a result, adding or modifying CDS views typically requires redeploying the database schema. - -To avoid schema redeployments when you add or update CDS views, annotate them with [@cds.persistence.skip](../../guides/databases#cds-persistence-skip). This annotation tells the CDS compiler to skip generating database views for these entities. Instead, the CAP Java runtime dynamically resolves such views at runtime. - -::: warning Limitations -Runtime views support only simple [CDS projections](../../cds/cdl#as-projection-on). They do not support complex views that use aggregations, unions, joins, or subqueries in the `FROM` clause. To read [draft-enabled](../fiori-drafts#reading-drafts) entities, set `cds.drafts.persistence` to `split`. [Calculated elements](../../cds/cdl#calculated-elements) are not yet supported in runtime views. -::: - -For example, consider the following CDS model and query: - -```cds -entity Books { - key id : UUID; - title : String; - stock : Integer; - author : Association to one Authors; -} -@cds.persistence.skip -entity BooksWithLowStock as projection on Books { - id, title, author.name as author -} where stock < 10; -``` -```sql -Select BooksWithLowStock where author = 'Kafka' -``` - -CAP Java provides two modes for resolving runtime views: - -**`cte` mode**: The runtime translates the view definition into a _Common Table Expression_ (CTE) and sends it with the query to the database. - -```sql -WITH BOOKSWITHLOWSTOCK_CTE AS ( - SELECT B.ID, - B.TITLE, - A.NAME AS "AUTHOR" - FROM BOOKS B - LEFT OUTER JOIN AUTHOR A ON B.AUTHOR_ID = A.ID - WHERE B.STOCK < 10 -) -SELECT ID, TITLE, AUTHOR AS "author" - FROM BOOKSWITHLOWSTOCK_CTE - WHERE A.NAME = ? -``` - -::: tip -CAP Java 4.x uses `cte` mode by default. In 3.10, enable it with **cds.sql.runtimeView.mode: cte**. -::: - -**`resolve` mode**: The runtime _resolves_ the view definition to the underlying persistence entities and executes the query directly against them. - -```sql -SELECT B.ID, B.TITLE, A.NAME AS "author" - FROM BOOKS AS B - LEFT OUTER JOIN AUTHORS AS A ON B.AUTHOR_ID = A.ID - WHERE B.STOCK < 10 AND A.NAME = ? -``` ## Using I/O Streams in Queries @@ -602,7 +622,7 @@ Map titleToDescription = For the entities defined in the data model, CAP Java SDK can generate interfaces for you through [a Maven plugin](../cqn-services/persistence-services#staticmodel). -### Using Entity References from Result Rows in CDS QL Statements {#entity-refs} +### Entity References {#entity-refs} For result rows that contain all key values of an entity, you get an [entity reference](./query-api#entity-refs) via the `ref()` method. This reference addresses the entity via the key values from the result row. From 75a0bca373e45c327e3efca5dc56d4e75bcb926f Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Thu, 12 Jun 2025 10:31:00 +0200 Subject: [PATCH 02/31] Update query-execution.md --- java/working-with-cql/query-execution.md | 51 ++++++++++++------------ 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 13e2d2f191..84d10e2ab4 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -225,25 +225,27 @@ long deleteCount = service.run(delete).rowCount(); ## Views and Projections { #views } -The CDS compiler automatically generates [DDL](../../guides/databases?impl-variant=java#generating-sql-ddl) files from your CDS model, including database views for all CDS [views and projections](../../cds/cdl#views-projections). +The CDS compiler generates [DDL](../../guides/databases?impl-variant=java#generating-sql-ddl) files from your CDS model, including database views for all CDS [views and projections](../../cds/cdl#views-projections). -These views are used to read data from the database, while write operations are resolved to the underlying entities, if possible. +Entity tables and views are deployed to the database. Read statements on CDS views target the database view, while write operations are resolved to the underlying entity table by the CAP Java runtime, when possible. -::: warning -Avoid using to-many associations on the select list of CDS views, as this prevents write operations and can lead to performance issues due to duplicating records on the DB. +::: warning Avoid to-many associations +Do not use to-many associations in the select clause of CDS views. This blocks write operations and can cause performance issues due to record duplication. ::: ### Runtime Views { #runtimeviews } -To add or update CDS views without redeploying the database schema, annotate your views with [@cds.persistence.skip](../../guides/databases#cds-persistence-skip). This tells the CDS compiler to skip generating database views for these entities. Instead, the CAP Java runtime dynamically resolves these views at runtime. +To add or update CDS views without redeploying the database schema, annotate your views with [@cds.persistence.skip](../../guides/databases#cds-persistence-skip). This tells the CDS compiler to skip generating database views for these entities, and the CAP Java runtime resolves them dynamically at runtime. ::: warning Limitations -Runtime views do not support complex views that use aggregations, unions, joins, or subqueries in the `FROM` clause. +Runtime views do not support complex views using aggregations, unions, joins, or subqueries in the `FROM` clause. +::: +::: tip Draft-enabled entities To read [draft-enabled](../fiori-drafts#reading-drafts) entities, set `cds.drafts.persistence` to `split`. ::: -For example, consider the following CDS model and query: +**Example** - consider the following CDS model and query: ```cds entity Books { @@ -258,7 +260,7 @@ entity BooksWithLowStock as projection on Books { } where stock < 10; ``` ```sql -Select BooksWithLowStock where author = 'Kafka' +SELECT from BooksWithLowStock where author = 'Kafka' ``` CAP Java provides two modes for resolving runtime views: @@ -283,7 +285,7 @@ SELECT ID, TITLE, AUTHOR AS "author" In CAP Java 3.10, enable `cte` mode with **cds.sql.runtimeView.mode: cte** ::: -**`resolve` mode**: The runtime _resolves_ the view definition to the underlying persistence entities and executes the query directly against them. +**`resolve` mode**: The runtime _resolves_ the view definition to the underlying persistence entities and executes the query directly against the corresponding tables. ```sql SELECT B.ID, B.TITLE, A.NAME AS "author" @@ -297,23 +299,23 @@ Expands to other runtime views and complex draft queries are not supported. ::: -### Write through Views { #updatable-views} +### Write through Views { #updatable-views } -To run [Insert](./query-api#insert), [Upsert](./query-api#upsert), [Update](./query-api#update), and [Delete](./query-api#delete) statements on CDS views, the CAP Java runtime resolves them to the underlying entity definitions, if possible - similar to the runtime view *resolve* mode for queries. +You can run [Insert](./query-api#insert), [Upsert](./query-api#upsert), [Update](./query-api#update), and [Delete](./query-api#delete) statements on CDS views. If possible, the CAP Java runtime resolves these to the underlying entity definitions—similar to the [runtime view](#runtimeviews) *resolve* mode for queries. -When delegating queries between Application Services and Remote Services, statements are also resolved to the entity definitions of the targeted service. +When delegating queries between Application Services and Remote Services, statements are also resolved to the targeted service's entity definitions. -Views and projections can be resolved for write operations if the following conditions are met: +Write operations on CDS views are supported if: -- The view definition does not use any other clause than `columns` and `excluding` - `join`, `union` and `where` are not supported. -- The projection includes all key elements; with the exception of insert operations with generated UUID keys. -- The projection includes all elements with a `not null` constraint, unless they have a default value. -- The projection must not include [path expressions](../../cds/cql#path-expressions) using to-many associations. -- Projections targeting remote OData services must not include calculated elements. +- The view definition uses only `columns` and `excluding` (no `join`, `union`, or `where`). +- The projection includes all key elements (except for insert operations with generated UUID keys). +- The projection includes all `not null` elements, unless they have a default value. +- The projection does not include [path expressions](../../cds/cql#path-expressions) using *to-many* associations. +- Projections targeting remote OData services do not include calculated elements. -For [Insert](./query-api#insert) or [Update](./query-api#update) operations, if the projection contains functions or expressions, these values are ignored. +For [Insert](./query-api#insert) or [Update](./query-api#update), values for functions and expressions in the projection are ignored. -Path expressions navigating *to-one* compositions, can be used in projections as shown by `headerStatus` in the following example, which includes the element `status` of the `OrderHeader` entity. +You can use path expressions navigating *to-one* compositions, as shown by `headerStatus` in this example: ```cds entity Order as projection on bookshop.Order; @@ -326,13 +328,12 @@ entity Order as projection on bookshop.Order { } excluding { status }; ``` -::: warning Path Expressions using Associations are readonly -Path expressions navigating associations are by default [not writable](#cascading-over-associations) and need to be annotated with [@readonly](../../guides/providing-services#readonly). +::: warning Path Expressions using associations are readonly +Path expressions navigating associations are [not writable](#cascading-over-associations) by default and must be annotated with [@readonly](../../guides/providing-services#readonly) to avoid issues on write. ::: -Write operations on views that cannot be resolved by the CAP Java runtime remain unmodified -- For the Persistence Service, this means the runtime _attempts_ to execute the write operation on the database view. Whether this execution is possible is [database dependent](../cqn-services/persistence-services#database-support). -- For Application Services and Remote Services, the targeted service will reject the statement. +If a view cannot be resolved by the CAP Java runtime, the write operation is attempted directly on the database view (Persistence Service), or rejected (Application/Remote Services). See [database support](../cqn-services/persistence-services#database-support) for details. + ## Concurrency Control From aab143d09f373a3fa0de0b0b32d7ab0b408745b3 Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Thu, 12 Jun 2025 11:44:40 +0200 Subject: [PATCH 03/31] Update query-execution.md --- java/working-with-cql/query-execution.md | 36 ++++++++++++++---------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 84d10e2ab4..2c2301f466 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -301,39 +301,45 @@ Expands to other runtime views and complex draft queries are not supported. ### Write through Views { #updatable-views } -You can run [Insert](./query-api#insert), [Upsert](./query-api#upsert), [Update](./query-api#update), and [Delete](./query-api#delete) statements on CDS views. If possible, the CAP Java runtime resolves these to the underlying entity definitions—similar to the [runtime view](#runtimeviews) *resolve* mode for queries. +You can run [Insert](./query-api#insert), [Upsert](./query-api#upsert), and [Update](./query-api#update) statements on CDS views. If possible, the CAP Java runtime resolves these to the underlying entity definitions—similar to the [runtime view](#runtimeviews) *resolve* mode for queries. When delegating queries between Application Services and Remote Services, statements are also resolved to the targeted service's entity definitions. Write operations on CDS views are supported if: -- The view definition uses only `columns` and `excluding` (no `join`, `union`, or `where`). -- The projection includes all key elements (except for insert operations with generated UUID keys). -- The projection includes all `not null` elements, unless they have a default value. +- The view definition uses only *columns* and *excluding* (no *join*, *union*, or *where*). +- The projection includes all *not null* elements (incl. keys), unless they have a default or generated value. - The projection does not include [path expressions](../../cds/cql#path-expressions) using *to-many* associations. -- Projections targeting remote OData services do not include calculated elements. +- Projections targeting *remote OData* services must not include calculated elements. -For [Insert](./query-api#insert) or [Update](./query-api#update), values for functions and expressions in the projection are ignored. - -You can use path expressions navigating *to-one* compositions, as shown by `headerStatus` in this example: +You can use path expressions navigating *to-one* compositions, as shown by `headerStatus`: ```cds -entity Order as projection on bookshop.Order; -entity Order as projection on bookshop.Order { ID, status as state }; +// CDS views supporting write operations +entity Order as projection on bookshop.Order excluding { status }; entity Order as projection on bookshop.Order { - ID, - header.status as headerStatus, - header.customer.name as customerName @readonly -} excluding { status }; + key ID, + header.status as headerStatus, + header.customer.name as customerName @readonly +}; ``` ::: warning Path Expressions using associations are readonly Path expressions navigating associations are [not writable](#cascading-over-associations) by default and must be annotated with [@readonly](../../guides/providing-services#readonly) to avoid issues on write. ::: -If a view cannot be resolved by the CAP Java runtime, the write operation is attempted directly on the database view (Persistence Service), or rejected (Application/Remote Services). See [database support](../cqn-services/persistence-services#database-support) for details. +Values for elements corresponding to expressions and functions in the projection of the CDS view are ignored in the data of [Insert](./query-api#insert), [Upsert](./query-api#upsert) and [Update](./query-api#update). + +If a view cannot be resolved by the CAP Java runtime, the write operation is either rejected (Application/Remote Services), or attempted directly on the database view (Persistence Service), see [database support](../cqn-services/persistence-services#database-support) for details. + +### Delete through Views { #delete-via-view } +[Delete](./query-api#delete) operations on CDS views are resolved to the underlying entity definitions by the CAP Java runtime, if possible. Delete via CDS views using *join*, *union*, or *where* is not supported. + +::: warning +[Cascading Delete](./query-execution#cascading-delete) is applied on persistence entity level, compositions that are added, changed or removed in CDS views are not considered by cascading delete. +::: ## Concurrency Control From 9bc426230ce70f1ca7b353d98a39446ebaf263ec Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Thu, 12 Jun 2025 14:13:13 +0200 Subject: [PATCH 04/31] Update query-execution.md --- java/working-with-cql/query-execution.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 2c2301f466..f50c7f162e 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -238,11 +238,11 @@ Do not use to-many associations in the select clause of CDS views. This blocks w To add or update CDS views without redeploying the database schema, annotate your views with [@cds.persistence.skip](../../guides/databases#cds-persistence-skip). This tells the CDS compiler to skip generating database views for these entities, and the CAP Java runtime resolves them dynamically at runtime. ::: warning Limitations -Runtime views do not support complex views using aggregations, unions, joins, or subqueries in the `FROM` clause. +Runtime views do not support aggregations, unions, joins, or subqueries in the FROM clause. ::: ::: tip Draft-enabled entities -To read [draft-enabled](../fiori-drafts#reading-drafts) entities, set `cds.drafts.persistence` to `split`. +For runtime views on [draft-enabled](../fiori-drafts#reading-drafts) entities, set *cds.drafts.persistence* to `split` and run draft queries through the [draft service](../fiori-drafts#draft-service). ::: **Example** - consider the following CDS model and query: @@ -263,7 +263,7 @@ entity BooksWithLowStock as projection on Books { SELECT from BooksWithLowStock where author = 'Kafka' ``` -CAP Java provides two modes for resolving runtime views: +CAP Java supports two modes for resolving runtime views: **`cte` mode**: The runtime translates the view definition into a _Common Table Expression_ (CTE) and sends it with the query to the database. @@ -285,6 +285,12 @@ SELECT ID, TITLE, AUTHOR AS "author" In CAP Java 3.10, enable `cte` mode with **cds.sql.runtimeView.mode: cte** ::: +::: warning Draft-enabling runtime views requires schema update +When [draft-enabling](../fiori-drafts#reading-drafts) a runtime view, a corresponding draft persistence table is created for the CDS view and a database schema update is required when changing the runtime view. + +[Draft activate](../fiori-drafts#editing-drafts) triggers a [write through view](#updatable-views) and the restrictions apply. +::: + **`resolve` mode**: The runtime _resolves_ the view definition to the underlying persistence entities and executes the query directly against the corresponding tables. ```sql @@ -295,7 +301,7 @@ SELECT B.ID, B.TITLE, A.NAME AS "author" ``` ::: warning Limitations of `resolve` mode -Expands to other runtime views and complex draft queries are not supported. +Expands to other runtime views, complex draft queries, and [draft-enabling](../fiori-drafts#reading-drafts) runtime views are not supported in *resolve* mode. ::: @@ -337,8 +343,8 @@ If a view cannot be resolved by the CAP Java runtime, the write operation is eit [Delete](./query-api#delete) operations on CDS views are resolved to the underlying entity definitions by the CAP Java runtime, if possible. Delete via CDS views using *join*, *union*, or *where* is not supported. -::: warning -[Cascading Delete](./query-execution#cascading-delete) is applied on persistence entity level, compositions that are added, changed or removed in CDS views are not considered by cascading delete. +::: warning Cascading Delete is applied on persistence entity level +Compositions that are added, changed or removed in CDS views are not considered by [cascading delete](./query-execution#cascading-delete). ::: From f5b71c9d7497a5f88d596cfe3b6dfda62945cff5 Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Thu, 12 Jun 2025 17:02:06 +0200 Subject: [PATCH 05/31] Update query-execution.md --- java/working-with-cql/query-execution.md | 25 +++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index f50c7f162e..bcd7783ebe 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -249,15 +249,15 @@ For runtime views on [draft-enabled](../fiori-drafts#reading-drafts) entities, s ```cds entity Books { - key id : UUID; + key ID : UUID; title : String; stock : Integer; author : Association to one Authors; } @cds.persistence.skip entity BooksWithLowStock as projection on Books { - id, title, author.name as author -} where stock < 10; + ID, title, author.name as author +} where stock < 10; // makes the view read only ``` ```sql SELECT from BooksWithLowStock where author = 'Kafka' @@ -301,13 +301,13 @@ SELECT B.ID, B.TITLE, A.NAME AS "author" ``` ::: warning Limitations of `resolve` mode -Expands to other runtime views, complex draft queries, and [draft-enabling](../fiori-drafts#reading-drafts) runtime views are not supported in *resolve* mode. +Using associations introduced by the view (mixins), as well as complex draft queries, and [draft-enabling](../fiori-drafts#reading-drafts) runtime views are not supported in *resolve* mode. ::: ### Write through Views { #updatable-views } -You can run [Insert](./query-api#insert), [Upsert](./query-api#upsert), and [Update](./query-api#update) statements on CDS views. If possible, the CAP Java runtime resolves these to the underlying entity definitions—similar to the [runtime view](#runtimeviews) *resolve* mode for queries. +You can run [Insert](./query-api#insert), [Upsert](./query-api#upsert), and [Update](./query-api#update) statements on CDS views. The CAP Java runtime attempts to resolve these to the underlying entity definitions—similar to the [runtime view](#runtimeviews) *resolve* mode for queries. When delegating queries between Application Services and Remote Services, statements are also resolved to the targeted service's entity definitions. @@ -327,17 +327,20 @@ entity Order as projection on bookshop.Order excluding { status }; entity Order as projection on bookshop.Order { key ID, header.status as headerStatus, - header.customer.name as customerName @readonly + header.customer.name as customerName @readonly, + items as lineItems // aliased composition }; ``` -::: warning Path Expressions using associations are readonly -Path expressions navigating associations are [not writable](#cascading-over-associations) by default and must be annotated with [@readonly](../../guides/providing-services#readonly) to avoid issues on write. -::: +[Deep write](./query-execution#deep-insert-upsert) via (aliased) compositions is supported if there are corresponding compositions in the underlying entity definition. Deep write via compositions only defined in the view (mixins) is not supported and the data for these composition targets is ignored. Values for elements corresponding to *expressions* and *functions* is ignored as well. + +::: warning Path Expressions +Path expressions navigating *associations* (e.g. *header.customer.name*) are [not writable](#cascading-over-associations) by default. To avoid issues on write, annotate them with [@readonly](../../guides/providing-services#readonly). -Values for elements corresponding to expressions and functions in the projection of the CDS view are ignored in the data of [Insert](./query-api#insert), [Upsert](./query-api#upsert) and [Update](./query-api#update). +Path expressions over *compositions* (e.g. *header.status*) are writable but require Insert data to include values for all *not null* elements of the target entity. +::: -If a view cannot be resolved by the CAP Java runtime, the write operation is either rejected (Application/Remote Services), or attempted directly on the database view (Persistence Service), see [database support](../cqn-services/persistence-services#database-support) for details. +If the CAP Java runtime cannot resolve a view, write operations are either rejected (Application/Remote Services) or attempted directly on the database view (Persistence Service). See [database support](../cqn-services/persistence-services#database-support) for details. ### Delete through Views { #delete-via-view } From f937dcbca59f044d355a539f3c530f7a9eff36fd Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Thu, 12 Jun 2025 17:25:20 +0200 Subject: [PATCH 06/31] deep write --- java/working-with-cql/query-execution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index bcd7783ebe..3b719d8505 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -332,7 +332,7 @@ entity Order as projection on bookshop.Order { }; ``` -[Deep write](./query-execution#deep-insert-upsert) via (aliased) compositions is supported if there are corresponding compositions in the underlying entity definition. Deep write via compositions only defined in the view (mixins) is not supported and the data for these composition targets is ignored. Values for elements corresponding to *expressions* and *functions* is ignored as well. +[Deep write](./query-execution#deep-insert-upsert) via (aliased) compositions is supported if there are corresponding compositions in the underlying entity definition. Deep write via compositions that are only defined in the view (mixins) is not supported and the data for such mixin compositions is ignored. Data for elements corresponding to *expressions* and *functions* is ignored as well. ::: warning Path Expressions Path expressions navigating *associations* (e.g. *header.customer.name*) are [not writable](#cascading-over-associations) by default. To avoid issues on write, annotate them with [@readonly](../../guides/providing-services#readonly). From 502a2ab34cc759c04b6d6eadb9f1f06d32155049 Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Mon, 16 Jun 2025 14:42:56 +0200 Subject: [PATCH 07/31] Update query-execution.md --- java/working-with-cql/query-execution.md | 45 ++++++++++++------------ 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 3b719d8505..9097eff471 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -230,21 +230,17 @@ The CDS compiler generates [DDL](../../guides/databases?impl-variant=java#genera Entity tables and views are deployed to the database. Read statements on CDS views target the database view, while write operations are resolved to the underlying entity table by the CAP Java runtime, when possible. ::: warning Avoid to-many associations -Do not use to-many associations in the select clause of CDS views. This blocks write operations and can cause performance issues due to record duplication. +Do not use to-many associations in the select clause of CDS views. This blocks write operations and can cause performance issues due to record duplication on read. ::: -### Runtime Views { #runtimeviews } +### Read from Runtime Views { #runtimeviews } To add or update CDS views without redeploying the database schema, annotate your views with [@cds.persistence.skip](../../guides/databases#cds-persistence-skip). This tells the CDS compiler to skip generating database views for these entities, and the CAP Java runtime resolves them dynamically at runtime. -::: warning Limitations +::: info Limitations Runtime views do not support aggregations, unions, joins, or subqueries in the FROM clause. ::: -::: tip Draft-enabled entities -For runtime views on [draft-enabled](../fiori-drafts#reading-drafts) entities, set *cds.drafts.persistence* to `split` and run draft queries through the [draft service](../fiori-drafts#draft-service). -::: - **Example** - consider the following CDS model and query: ```cds @@ -282,13 +278,7 @@ SELECT ID, TITLE, AUTHOR AS "author" ``` ::: tip -In CAP Java 3.10, enable `cte` mode with **cds.sql.runtimeView.mode: cte** -::: - -::: warning Draft-enabling runtime views requires schema update -When [draft-enabling](../fiori-drafts#reading-drafts) a runtime view, a corresponding draft persistence table is created for the CDS view and a database schema update is required when changing the runtime view. - -[Draft activate](../fiori-drafts#editing-drafts) triggers a [write through view](#updatable-views) and the restrictions apply. +In CAP Java 3.10, enable **cte** mode with *cds.sql.runtimeView.mode: cte* ::: **`resolve` mode**: The runtime _resolves_ the view definition to the underlying persistence entities and executes the query directly against the corresponding tables. @@ -300,10 +290,19 @@ SELECT B.ID, B.TITLE, A.NAME AS "author" WHERE B.STOCK < 10 AND A.NAME = ? ``` -::: warning Limitations of `resolve` mode +::: info Limitations of `resolve` mode Using associations introduced by the view (mixins), as well as complex draft queries, and [draft-enabling](../fiori-drafts#reading-drafts) runtime views are not supported in *resolve* mode. ::: +### Draft with Runtime Views { #draft-views } + +If you define runtime views on [draft-enabled](../fiori-drafts#reading-drafts) entities and want to run draft specific queries on these views, set the *cds.drafts.persistence* configuration to `split` and run the queries through the [Draft Service](../fiori-drafts#draft-service) or [Application Service](../cqn-services/application-services#application-services). The [Persistence Service](../cqn-services/persistence-services) only works for non-draft specific queries. + +::: warning Draft-enabling runtime views requires schema update +When [draft-enabling](../fiori-drafts#reading-drafts) a runtime view, a corresponding draft persistence table is created for this view and a database schema update is required when changing the runtime view. + +[Draft activate](../fiori-drafts#editing-drafts) updates the active entity via the runtime view, therefore the runtime view must fulfill all requirements of a [writable view](#updatable-views). +::: ### Write through Views { #updatable-views } @@ -326,21 +325,23 @@ entity Order as projection on bookshop.Order excluding { status }; entity Order as projection on bookshop.Order { key ID, - header.status as headerStatus, - header.customer.name as customerName @readonly, - items as lineItems // aliased composition + header.status as headerStatus, + header.customer.name as customerName @readonly, + items as lineItems, // aliased composition + toUpper(shipToCountry) as country : String // ignored on write }; ``` -[Deep write](./query-execution#deep-insert-upsert) via (aliased) compositions is supported if there are corresponding compositions in the underlying entity definition. Deep write via compositions that are only defined in the view (mixins) is not supported and the data for such mixin compositions is ignored. Data for elements corresponding to *expressions* and *functions* is ignored as well. +- Data for elements corresponding to *expressions* and *functions* (*country*) is ignored. +- [Deep write](./query-execution#deep-insert-upsert) via (aliased) compositions (*items*) is supported if there are corresponding compositions in the underlying entity definition. Deep write via compositions that are only defined in the view (mixins) is not supported and the data for such mixin compositions is ignored. -::: warning Path Expressions +::: warning Path Expressions in Views Path expressions navigating *associations* (e.g. *header.customer.name*) are [not writable](#cascading-over-associations) by default. To avoid issues on write, annotate them with [@readonly](../../guides/providing-services#readonly). -Path expressions over *compositions* (e.g. *header.status*) are writable but require Insert data to include values for all *not null* elements of the target entity. +Path expressions over *compositions* (e.g. *header.status*) are writable but require the Insert data to include values for all *not null* elements of the target entity. In the example above, the order header must have a generated key to support inserting new orders with a status. ::: -If the CAP Java runtime cannot resolve a view, write operations are either rejected (Application/Remote Services) or attempted directly on the database view (Persistence Service). See [database support](../cqn-services/persistence-services#database-support) for details. +If the CAP Java runtime cannot resolve a view, write operations are either rejected (Application/Remote Services) or attempted directly on the database view (Persistence Service). In the second case the execution depends on the [database support](../cqn-services/persistence-services#database-support). ### Delete through Views { #delete-via-view } From c421e251351e2a179dbc36a5cb1729c5f3da773e Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Mon, 16 Jun 2025 15:33:14 +0200 Subject: [PATCH 08/31] delete example --- java/working-with-cql/query-execution.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 9097eff471..6cde5e530d 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -229,6 +229,9 @@ The CDS compiler generates [DDL](../../guides/databases?impl-variant=java#genera Entity tables and views are deployed to the database. Read statements on CDS views target the database view, while write operations are resolved to the underlying entity table by the CAP Java runtime, when possible. +::: tip Avoid mixin compositions +Avoid introducing new compositions in CDS views and prefer associations instead, as [deep write](#updatable-views) and [cascading delete](#delete-via-view) are only supported for compositions in persistence entities. +::: ::: warning Avoid to-many associations Do not use to-many associations in the select clause of CDS views. This blocks write operations and can cause performance issues due to record duplication on read. ::: @@ -345,12 +348,30 @@ If the CAP Java runtime cannot resolve a view, write operations are either rejec ### Delete through Views { #delete-via-view } -[Delete](./query-api#delete) operations on CDS views are resolved to the underlying entity definitions by the CAP Java runtime, if possible. Delete via CDS views using *join*, *union*, or *where* is not supported. +The CAP Java runtime attempts to resolve [Delete](./query-api#delete) operations to the underlying entity definitions—similar to the [runtime view](#runtimeviews) *resolve* mode for queries. ::: warning Cascading Delete is applied on persistence entity level Compositions that are added, changed or removed in CDS views are not considered by [cascading delete](./query-execution#cascading-delete). ::: +For example, the following CDS model defines `Order` with header and items, and `OrderView` which excludes header and exposes items as `lineItems`: + +```cds +entity Order : cuid, managed { + header : Composition of one OrderHeader; + items : Composition of many OrderItem on items.parent = $self; +} +entity OrderView as projection on db.Order { + ID, + items as lineItems, + delivery : Composition of one Delivery on delivery.order = $self +} +``` +```sql +DELETE from OrderView where ID = 42 +``` +The delete operation is resolved to the underlying `Order` entity with ID *42* and cascades over the `header` and `items` compositions. The `delivery` composition, which is only defined in the view, is ignored and does not cascade the delete operation to `Delivery`. + ## Concurrency Control From 6ddfb0b674aa48288d16540fc967cafe4df7ee6d Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Mon, 16 Jun 2025 16:03:28 +0200 Subject: [PATCH 09/31] draft --- java/working-with-cql/query-execution.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 6cde5e530d..ff4b956f9a 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -301,10 +301,10 @@ Using associations introduced by the view (mixins), as well as complex draft que If you define runtime views on [draft-enabled](../fiori-drafts#reading-drafts) entities and want to run draft specific queries on these views, set the *cds.drafts.persistence* configuration to `split` and run the queries through the [Draft Service](../fiori-drafts#draft-service) or [Application Service](../cqn-services/application-services#application-services). The [Persistence Service](../cqn-services/persistence-services) only works for non-draft specific queries. -::: warning Draft-enabling runtime views requires schema update -When [draft-enabling](../fiori-drafts#reading-drafts) a runtime view, a corresponding draft persistence table is created for this view and a database schema update is required when changing the runtime view. +::: warning Avoid draft-enabling runtime views +[Draft-enabling](../fiori-drafts#reading-drafts) runtime views is only supported in *cte* mode. The cds-compiler creates a corresponding draft persistence table for the view and a database schema update is required each time the runtime view is changed. -[Draft activate](../fiori-drafts#editing-drafts) updates the active entity via the runtime view, therefore the runtime view must fulfill all requirements of a [writable view](#updatable-views). +[Draft activate](../fiori-drafts#editing-drafts) updates the active entity via the runtime view, therefore the view must fulfill all requirements of an [updatable view](#updatable-views). ::: ### Write through Views { #updatable-views } From 5bf74f2360b0369ec0226504fbb6da7508b9aa3d Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Mon, 16 Jun 2025 16:21:49 +0200 Subject: [PATCH 10/31] subsections --- java/working-with-cql/query-execution.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index ff4b956f9a..f53a1f8ca2 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -264,7 +264,9 @@ SELECT from BooksWithLowStock where author = 'Kafka' CAP Java supports two modes for resolving runtime views: -**`cte` mode**: The runtime translates the view definition into a _Common Table Expression_ (CTE) and sends it with the query to the database. +#### CTE mode + +This is the default mode in CAP Java `4.x`. The runtime translates the view definition into a _Common Table Expression_ (CTE) and sends it with the query to the database. ```sql WITH BOOKSWITHLOWSTOCK_CTE AS ( @@ -280,11 +282,13 @@ SELECT ID, TITLE, AUTHOR AS "author" WHERE A.NAME = ? ``` -::: tip -In CAP Java 3.10, enable **cte** mode with *cds.sql.runtimeView.mode: cte* +::: tip CAP Java 3.10 +Enable *cte* mode with *cds.sql.runtimeView.mode: cte* ::: -**`resolve` mode**: The runtime _resolves_ the view definition to the underlying persistence entities and executes the query directly against the corresponding tables. +#### Resolve mode + +The runtime _resolves_ the view definition to the underlying persistence entities and executes the query directly against the corresponding tables. ```sql SELECT B.ID, B.TITLE, A.NAME AS "author" @@ -309,7 +313,7 @@ If you define runtime views on [draft-enabled](../fiori-drafts#reading-drafts) e ### Write through Views { #updatable-views } -You can run [Insert](./query-api#insert), [Upsert](./query-api#upsert), and [Update](./query-api#update) statements on CDS views. The CAP Java runtime attempts to resolve these to the underlying entity definitions—similar to the [runtime view](#runtimeviews) *resolve* mode for queries. +You can run [Insert](./query-api#insert), [Upsert](./query-api#upsert), and [Update](./query-api#update) statements on CDS views. The CAP Java runtime attempts to resolve these to the underlying entity definitions—similar to the runtime view [resolve mode](query-execution#resolve-mode) for queries. When delegating queries between Application Services and Remote Services, statements are also resolved to the targeted service's entity definitions. @@ -348,7 +352,7 @@ If the CAP Java runtime cannot resolve a view, write operations are either rejec ### Delete through Views { #delete-via-view } -The CAP Java runtime attempts to resolve [Delete](./query-api#delete) operations to the underlying entity definitions—similar to the [runtime view](#runtimeviews) *resolve* mode for queries. +The CAP Java runtime attempts to resolve [Delete](./query-api#delete) operations to the underlying entity definitions—similar to the runtime view [resolve mode](query-execution#resolve-mode) for queries. ::: warning Cascading Delete is applied on persistence entity level Compositions that are added, changed or removed in CDS views are not considered by [cascading delete](./query-execution#cascading-delete). From b30d4277215df9b877f927359d3d0fbcb0ef101b Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Wed, 18 Jun 2025 15:09:08 +0200 Subject: [PATCH 11/31] Restructure --- java/working-with-cql/query-execution.md | 176 +++++++++++++---------- 1 file changed, 101 insertions(+), 75 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index f53a1f8ca2..a004eca40c 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -225,25 +225,93 @@ long deleteCount = service.run(delete).rowCount(); ## Views and Projections { #views } -The CDS compiler generates [DDL](../../guides/databases?impl-variant=java#generating-sql-ddl) files from your CDS model, including database views for all CDS [views and projections](../../cds/cdl#views-projections). +The CDS compiler generates [DDL](../../guides/databases?impl-variant=java#generating-sql-ddl) files from your CDS model, by default including database views for all CDS [views and projections](../../cds/cdl#views-projections). These tables and views are deployed to the [database](../cqn-services/persistence-services#database-support). -Entity tables and views are deployed to the database. Read statements on CDS views target the database view, while write operations are resolved to the underlying entity table by the CAP Java runtime, when possible. +CDS views can be defined by simple [projections](../../cds/cdl#as-projection-on) or complex [selects](../../cds/cdl#as-select-from) including *joins*, *unions*, and *aggregations*. Read statements on CDS views target the generated database views. -::: tip Avoid mixin compositions -Avoid introducing new compositions in CDS views and prefer associations instead, as [deep write](#updatable-views) and [cascading delete](#delete-via-view) are only supported for compositions in persistence entities. +For [write](#updatable-views) and [delete](#delete-via-view) operations, the CAP Java runtime attempts to resolve the CDS views to their underlying persistence entities, which is only supported for simple projections. + +::: warning Avoid selecting to-many Associations +Do not use [*to-many associations*](../../cds/cdl#to-many-associations) in the select clause of CDS views. This blocks write operations and may cause performance issues due to record duplication on read. ::: -::: warning Avoid to-many associations -Do not use to-many associations in the select clause of CDS views. This blocks write operations and can cause performance issues due to record duplication on read. +::: warning Avoid Composition Definitions in Views +Avoid [defining](../../cds/cql#association-definitions) new *compositions* in CDS views and prefer *associations* instead, as [deep write](#updatable-views) and [cascading delete](#delete-via-view) are only supported for compositions in persistence entities. ::: -### Read from Runtime Views { #runtimeviews } +### Write through Views { #updatable-views } + +You can run [Insert](./query-api#insert), [Upsert](./query-api#upsert), and [Update](./query-api#update) statements on CDS views that are writable on the database or can be resolved to a single persistence entity by the CAP Java runtime. + +CDS views must fulfill the following requirements to be resolvable: + +- The view is a simple [projection](../../cds/cdl#as-projection-on), not using *aggregations*, *join*, *union*, or *where*. +- The projection includes all *not null* elements (incl. keys), unless they have a default or generated value. +- The projection does not include [path expressions](../../cds/cql#path-expressions) using *to-many* associations. + +If the runtime cannot resolve a view, the write operation is executed directly on the database view and the execution depends on the [database](../cqn-services/persistence-services#database-support) support. + +For example, the following CDS model defines two resolvable views on the `Order` entity, which has a to-many *items* and a to-one *header* composition to a Header entity with a to-one customer *association*. In the projection, you can use path expressions as shown by *headerStatus* (writable) and *customerName* (read-only): + +```cds +// CDS views supporting write operations +entity OrderView1 as projection on Order excluding { createdBy }; + +entity OrderView2 as projection on OrderView1 { + key ID, + header.status as headerStatus, // writable composition path + header.customer.name as customerName @readonly, + items as lineItems, // writable composition + toUpper(shipToCountry) as country : String // ignored on write +}; +``` +```sql +UPDATE entity OrderView2 + { ID: 42, headerStatus: 'Processing', lineItems: [{ID: 1, book:251}] } +``` +- Data for elements corresponding to *expressions* and *functions* (*country*) is ignored. +- [Deep write](./query-execution#deep-insert-upsert) via (aliased) compositions (*lineItems*) is supported if there are corresponding compositions (*items*) in the underlying entity definition. Deep write via compositions that are only defined in the view (for example via [mixins](../../cds/cql#association-definitions)) is not supported and the data is ignored. +- [Path expressions](../../cds/cql#path-expressions) over compositions (*header.status*) are writable. For [Inserts](./query-api#insert), the view must expose all *not null* elements of the target entity and the data must include values for all of them. In the example above, the order header must have a generated key to support inserting new orders with a value for *headerStatus*. + + ::: warning Path Expressions over Associations + Path expressions navigating *associations* (*header.customer.name*) are [not writable](#cascading-over-associations) by default. To avoid issues on write, annotate them with [@readonly](../../guides/providing-services#readonly). + ::: -To add or update CDS views without redeploying the database schema, annotate your views with [@cds.persistence.skip](../../guides/databases#cds-persistence-skip). This tells the CDS compiler to skip generating database views for these entities, and the CAP Java runtime resolves them dynamically at runtime. +### Delete through Views { #delete-via-view } + +The CAP Java runtime attempts to resolve [Deletes](./query-api#delete) on CDS views to the underlying persistence entity definitions and the [write through views](#updatable-views) restrictions apply accordingly. + +If a view cannot be resolved, the delete operation is executed directly on the database view and the execution depends on the [database](../cqn-services/persistence-services#database-support) support. -::: info Limitations -Runtime views do not support aggregations, unions, joins, or subqueries in the FROM clause. +::: danger Delete Cascades on Persistence Entity Level +[Cascading delete](./query-execution#cascading-delete) is applied on persistence entity level only, including compositions that are excluded from the view. +Compositions that are [added](../../cds/cql#association-definitions) in CDS views, as well as changes to compositions (such as filters and redirects) are not considered. ::: +For example, the following CDS model defines `Order` with header and items, and `OrderView` which excludes header and exposes items as `lineItems`: + +```cds +entity Order : cuid, managed { + header : Composition of one OrderHeader; + items : Composition of many OrderItem on items.parent = $self; +} +entity OrderView as projection on db.Order { + ID, + items as lineItems, + delivery : Composition of one Delivery on delivery.order = $self +} +``` +```sql +DELETE from OrderView where ID = 42 +``` +The delete operation is resolved to the underlying `Order` entity with ID *42* and cascades over the `header` and `items` compositions. The `delivery` composition, which is only defined in the view, is ignored and does not cascade the delete operation to `Delivery`. + +### Runtime Views { #runtimeviews } + +To add or update CDS views without redeploying the database schema, annotate them with [@cds.persistence.skip](../../guides/databases#cds-persistence-skip). This tells the CDS compiler to skip generating database views for these CDS views, and the CAP Java runtime resolves them dynamically on each request. + + +Runtime views must be simple [projections](../../cds/cdl#as-projection-on), not using *aggregations*, *join*, *union* or *subqueries* in the *from* clause, but may have a *where* condition if they are only used to read. On write, the restrictions for [write through views](#updatable-views) apply in the same way as for standard CDS views. + **Example** - consider the following CDS model and query: ```cds @@ -262,9 +330,9 @@ entity BooksWithLowStock as projection on Books { SELECT from BooksWithLowStock where author = 'Kafka' ``` -CAP Java supports two modes for resolving runtime views: +CAP Java supports two modes for resolving runtime views on read: -#### CTE mode +#### Read in `CTE` mode { #rtview-cte } This is the default mode in CAP Java `4.x`. The runtime translates the view definition into a _Common Table Expression_ (CTE) and sends it with the query to the database. @@ -282,11 +350,15 @@ SELECT ID, TITLE, AUTHOR AS "author" WHERE A.NAME = ? ``` +::: info Limitations of `cte` mode +[Pessimistic locking](#pessimistic-locking) queries on runtime views in *cte* mode are not supported on SAP HANA. +::: + ::: tip CAP Java 3.10 Enable *cte* mode with *cds.sql.runtimeView.mode: cte* ::: -#### Resolve mode +#### Read in `Resolve` mode { #rtview-resolve } The runtime _resolves_ the view definition to the underlying persistence entities and executes the query directly against the corresponding tables. @@ -298,83 +370,37 @@ SELECT B.ID, B.TITLE, A.NAME AS "author" ``` ::: info Limitations of `resolve` mode -Using associations introduced by the view (mixins), as well as complex draft queries, and [draft-enabling](../fiori-drafts#reading-drafts) runtime views are not supported in *resolve* mode. +Using associations that are only [defined](../../cds/cql#association-definitions) in the view, as well as complex draft queries are not supported in *resolve* mode. ::: -### Draft with Runtime Views { #draft-views } - -If you define runtime views on [draft-enabled](../fiori-drafts#reading-drafts) entities and want to run draft specific queries on these views, set the *cds.drafts.persistence* configuration to `split` and run the queries through the [Draft Service](../fiori-drafts#draft-service) or [Application Service](../cqn-services/application-services#application-services). The [Persistence Service](../cqn-services/persistence-services) only works for non-draft specific queries. - -::: warning Avoid draft-enabling runtime views -[Draft-enabling](../fiori-drafts#reading-drafts) runtime views is only supported in *cte* mode. The cds-compiler creates a corresponding draft persistence table for the view and a database schema update is required each time the runtime view is changed. - -[Draft activate](../fiori-drafts#editing-drafts) updates the active entity via the runtime view, therefore the view must fulfill all requirements of an [updatable view](#updatable-views). -::: - -### Write through Views { #updatable-views } - -You can run [Insert](./query-api#insert), [Upsert](./query-api#upsert), and [Update](./query-api#update) statements on CDS views. The CAP Java runtime attempts to resolve these to the underlying entity definitions—similar to the runtime view [resolve mode](query-execution#resolve-mode) for queries. - -When delegating queries between Application Services and Remote Services, statements are also resolved to the targeted service's entity definitions. - -Write operations on CDS views are supported if: +### Draft Queries on Views { #draft-views } -- The view definition uses only *columns* and *excluding* (no *join*, *union*, or *where*). -- The projection includes all *not null* elements (incl. keys), unless they have a default or generated value. -- The projection does not include [path expressions](../../cds/cql#path-expressions) using *to-many* associations. -- Projections targeting *remote OData* services must not include calculated elements. +When draft-enabling a CDS view, the CDS Compiler creates a corresponding draft persistence table for this view. [Draft activate](../fiori-drafts#editing-drafts) updates the active entity via the view, therefore -You can use path expressions navigating *to-one* compositions, as shown by `headerStatus`: +- [Draft-enabled](../fiori-drafts#reading-drafts) CDS views must fulfill all requirements of [updatable views](#updatable-views). -```cds -// CDS views supporting write operations -entity Order as projection on bookshop.Order excluding { status }; - -entity Order as projection on bookshop.Order { - key ID, - header.status as headerStatus, - header.customer.name as customerName @readonly, - items as lineItems, // aliased composition - toUpper(shipToCountry) as country : String // ignored on write -}; -``` +Remember to run draft specific queries through the [Draft Service](../fiori-drafts#draft-service) or [Application Service](../cqn-services/application-services#application-services). The [Persistence Service](../cqn-services/persistence-services) only works for non-draft specific queries. -- Data for elements corresponding to *expressions* and *functions* (*country*) is ignored. -- [Deep write](./query-execution#deep-insert-upsert) via (aliased) compositions (*items*) is supported if there are corresponding compositions in the underlying entity definition. Deep write via compositions that are only defined in the view (mixins) is not supported and the data for such mixin compositions is ignored. -::: warning Path Expressions in Views -Path expressions navigating *associations* (e.g. *header.customer.name*) are [not writable](#cascading-over-associations) by default. To avoid issues on write, annotate them with [@readonly](../../guides/providing-services#readonly). +::: tip Draft Queries on Runtime Views +If you define runtime views on [draft-enabled](../fiori-drafts#reading-drafts) entities and want to run draft specific queries on these views, set the *cds.drafts.persistence* configuration to `split`. +::: -Path expressions over *compositions* (e.g. *header.status*) are writable but require the Insert data to include values for all *not null* elements of the target entity. In the example above, the order header must have a generated key to support inserting new orders with a status. +::: warning Avoid draft-enabling Runtime Views +Draft-enabling runtime views is only supported in [*CTE*](#rtview-cte) mode and requires a schema deployment to update the draft table when the runtime view is changed. ::: -If the CAP Java runtime cannot resolve a view, write operations are either rejected (Application/Remote Services) or attempted directly on the database view (Persistence Service). In the second case the execution depends on the [database support](../cqn-services/persistence-services#database-support). +### Views on Remote Services -### Delete through Views { #delete-via-view } +When delegating queries between Application Services and Remote Services, statements are resolved to the targeted service's entity definitions by the CAP Java runtime. -The CAP Java runtime attempts to resolve [Delete](./query-api#delete) operations to the underlying entity definitions—similar to the runtime view [resolve mode](query-execution#resolve-mode) for queries. +For read, the CDS views are resolved similar to the runtime view [resolve](#rtview-resolve) mode. For write operations, views targeting *remote OData* services must -::: warning Cascading Delete is applied on persistence entity level -Compositions that are added, changed or removed in CDS views are not considered by [cascading delete](./query-execution#cascading-delete). -::: +- fulfill all requirements of [writable views](#updatable-views) +- not include [calculated elements](../../cds/cdl#calculated-elements) -For example, the following CDS model defines `Order` with header and items, and `OrderView` which excludes header and exposes items as `lineItems`: +If a view cannot be resolved, read and write operations are rejected. -```cds -entity Order : cuid, managed { - header : Composition of one OrderHeader; - items : Composition of many OrderItem on items.parent = $self; -} -entity OrderView as projection on db.Order { - ID, - items as lineItems, - delivery : Composition of one Delivery on delivery.order = $self -} -``` -```sql -DELETE from OrderView where ID = 42 -``` -The delete operation is resolved to the underlying `Order` entity with ID *42* and cascades over the `header` and `items` compositions. The `delivery` composition, which is only defined in the view, is ignored and does not cascade the delete operation to `Delivery`. ## Concurrency Control From a0d97be003e5662152612e3d6152c405eec72b34 Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Mon, 23 Jun 2025 12:39:00 +0200 Subject: [PATCH 12/31] Update query-execution.md --- java/working-with-cql/query-execution.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index a004eca40c..1d987cd07a 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -309,10 +309,9 @@ The delete operation is resolved to the underlying `Order` entity with ID *42* a To add or update CDS views without redeploying the database schema, annotate them with [@cds.persistence.skip](../../guides/databases#cds-persistence-skip). This tells the CDS compiler to skip generating database views for these CDS views, and the CAP Java runtime resolves them dynamically on each request. +Runtime views must be simple [projections](../../cds/cdl#as-projection-on), not using *aggregations*, *join*, *union* or *subqueries* in the *from* clause, but may have a *where* condition if they are only used to read. On write, the restrictions for [write through views](#updatable-views) apply in the same way as for standard CDS views. However, if a runtime view cannot be resolved, a fallback to database views is not possible, and the statement fails with an error. -Runtime views must be simple [projections](../../cds/cdl#as-projection-on), not using *aggregations*, *join*, *union* or *subqueries* in the *from* clause, but may have a *where* condition if they are only used to read. On write, the restrictions for [write through views](#updatable-views) apply in the same way as for standard CDS views. - -**Example** - consider the following CDS model and query: +**Read via Runtime Views** - consider the following CDS model and query: ```cds entity Books { @@ -383,7 +382,7 @@ Remember to run draft specific queries through the [Draft Service](../fiori-draf ::: tip Draft Queries on Runtime Views -If you define runtime views on [draft-enabled](../fiori-drafts#reading-drafts) entities and want to run draft specific queries on these views, set the *cds.drafts.persistence* configuration to `split`. +If you define runtime views on [draft-enabled](../fiori-drafts#reading-drafts) entities and want to run draft specific queries on these views, set the [*cds.drafts.persistence*](../fiori-drafts#reading-drafts) configuration to `split`. ::: ::: warning Avoid draft-enabling Runtime Views @@ -402,7 +401,6 @@ For read, the CDS views are resolved similar to the runtime view [resolve](#rtvi If a view cannot be resolved, read and write operations are rejected. - ## Concurrency Control Concurrency control allows protecting your data against unexpected concurrent changes. From f164810a715518c206fd8c4a53502a5945f881f1 Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Wed, 25 Jun 2025 13:11:17 +0200 Subject: [PATCH 13/31] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: René Jeglinsky --- java/working-with-cql/query-execution.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 1d987cd07a..44a929174f 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -331,7 +331,7 @@ SELECT from BooksWithLowStock where author = 'Kafka' CAP Java supports two modes for resolving runtime views on read: -#### Read in `CTE` mode { #rtview-cte } +#### Read in `cte` mode { #rtview-cte } This is the default mode in CAP Java `4.x`. The runtime translates the view definition into a _Common Table Expression_ (CTE) and sends it with the query to the database. @@ -357,7 +357,7 @@ SELECT ID, TITLE, AUTHOR AS "author" Enable *cte* mode with *cds.sql.runtimeView.mode: cte* ::: -#### Read in `Resolve` mode { #rtview-resolve } +#### Read in `resolve` mode { #rtview-resolve } The runtime _resolves_ the view definition to the underlying persistence entities and executes the query directly against the corresponding tables. From 67573ef2e8294e2529c7fc1926344f3b8a8c3206 Mon Sep 17 00:00:00 2001 From: Rene Jeglinsky Date: Wed, 25 Jun 2025 14:20:22 +0200 Subject: [PATCH 14/31] edit --- java/working-with-cql/query-execution.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 1d987cd07a..eb96924dba 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -311,7 +311,12 @@ To add or update CDS views without redeploying the database schema, annotate the Runtime views must be simple [projections](../../cds/cdl#as-projection-on), not using *aggregations*, *join*, *union* or *subqueries* in the *from* clause, but may have a *where* condition if they are only used to read. On write, the restrictions for [write through views](#updatable-views) apply in the same way as for standard CDS views. However, if a runtime view cannot be resolved, a fallback to database views is not possible, and the statement fails with an error. -**Read via Runtime Views** - consider the following CDS model and query: +CAP Java supports two modes for resolving runtime views on read: +- `CTE` +- `Resolve` + + +In the following section about `CTE` and `Resolve` we use the following CDS model and query as example: ```cds entity Books { @@ -329,7 +334,6 @@ entity BooksWithLowStock as projection on Books { SELECT from BooksWithLowStock where author = 'Kafka' ``` -CAP Java supports two modes for resolving runtime views on read: #### Read in `CTE` mode { #rtview-cte } @@ -374,9 +378,12 @@ Using associations that are only [defined](../../cds/cql#association-definitions ### Draft Queries on Views { #draft-views } -When draft-enabling a CDS view, the CDS Compiler creates a corresponding draft persistence table for this view. [Draft activate](../fiori-drafts#editing-drafts) updates the active entity via the view, therefore +When draft-enabling a CDS view, the CDS Compiler creates a corresponding draft persistence table for this view. [Draft activate](../fiori-drafts#editing-drafts) updates the active entity via the view. -- [Draft-enabled](../fiori-drafts#reading-drafts) CDS views must fulfill all requirements of [updatable views](#updatable-views). +That means: +
+-> [Draft-enabled](../fiori-drafts#reading-drafts) CDS views must fulfill all requirements of [updatable views](#updatable-views). +{.indent} Remember to run draft specific queries through the [Draft Service](../fiori-drafts#draft-service) or [Application Service](../cqn-services/application-services#application-services). The [Persistence Service](../cqn-services/persistence-services) only works for non-draft specific queries. From 28d042331ec2bf5d2ae93ddff83874c8e5cfd624 Mon Sep 17 00:00:00 2001 From: Rene Jeglinsky Date: Wed, 25 Jun 2025 14:20:54 +0200 Subject: [PATCH 15/31] lowercase --- java/working-with-cql/query-execution.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index cd1cbe962a..dc6d9f5a8e 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -312,8 +312,8 @@ To add or update CDS views without redeploying the database schema, annotate the Runtime views must be simple [projections](../../cds/cdl#as-projection-on), not using *aggregations*, *join*, *union* or *subqueries* in the *from* clause, but may have a *where* condition if they are only used to read. On write, the restrictions for [write through views](#updatable-views) apply in the same way as for standard CDS views. However, if a runtime view cannot be resolved, a fallback to database views is not possible, and the statement fails with an error. CAP Java supports two modes for resolving runtime views on read: -- `CTE` -- `Resolve` +- `cte` +- `resolve` In the following section about `CTE` and `Resolve` we use the following CDS model and query as example: From b79db42f02e7aab605767666563670abef2c847a Mon Sep 17 00:00:00 2001 From: Rene Jeglinsky Date: Wed, 25 Jun 2025 14:21:16 +0200 Subject: [PATCH 16/31] again...lowercase --- java/working-with-cql/query-execution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index dc6d9f5a8e..15f6a60f20 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -316,7 +316,7 @@ CAP Java supports two modes for resolving runtime views on read: - `resolve` -In the following section about `CTE` and `Resolve` we use the following CDS model and query as example: +In the following section about `cte` and `resolve` we use the following CDS model and query as example: ```cds entity Books { From e2e7751c9cc6c16ed955adac1f3af94859019522 Mon Sep 17 00:00:00 2001 From: Rene Jeglinsky Date: Wed, 25 Jun 2025 14:32:37 +0200 Subject: [PATCH 17/31] fix link --- java/working-with-cql/query-execution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 15f6a60f20..5bf0087461 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -385,7 +385,7 @@ That means: -> [Draft-enabled](../fiori-drafts#reading-drafts) CDS views must fulfill all requirements of [updatable views](#updatable-views). {.indent} -Remember to run draft specific queries through the [Draft Service](../fiori-drafts#draft-service) or [Application Service](../cqn-services/application-services#application-services). The [Persistence Service](../cqn-services/persistence-services) only works for non-draft specific queries. +Remember to run draft specific queries through the [Draft Service](../fiori-drafts#draftservices) or [Application Service](../cqn-services/application-services#application-services). The [Persistence Service](../cqn-services/persistence-services) only works for non-draft specific queries. ::: tip Draft Queries on Runtime Views From c2af4ef13e2474540ced48e5e0612abe8925c3c4 Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Fri, 27 Jun 2025 16:50:17 +0200 Subject: [PATCH 18/31] improve introduction --- java/working-with-cql/query-execution.md | 27 ++++++++++++++---------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 5bf0087461..1b438e3c82 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -225,12 +225,22 @@ long deleteCount = service.run(delete).rowCount(); ## Views and Projections { #views } -The CDS compiler generates [DDL](../../guides/databases?impl-variant=java#generating-sql-ddl) files from your CDS model, by default including database views for all CDS [views and projections](../../cds/cdl#views-projections). These tables and views are deployed to the [database](../cqn-services/persistence-services#database-support). +With CDS [views](../../cds/cdl#views-projections) you can derive new entities from existing ones, for example to rename or exclude certain elements, or to add [virtual elements](../../cds/cdl#virtual-elements-in-views) for specific use cases. -CDS views can be defined by simple [projections](../../cds/cdl#as-projection-on) or complex [selects](../../cds/cdl#as-select-from) including *joins*, *unions*, and *aggregations*. Read statements on CDS views target the generated database views. +The CDS compiler generates [DDL](../../guides/databases?impl-variant=java#generating-sql-ddl) files from your CDS model, including SQL views for the CDS views. These views are deployed to the [database](../cqn-services/persistence-services#database-support) and used by the CAP runtime to read data. -For [write](#updatable-views) and [delete](#delete-via-view) operations, the CAP Java runtime attempts to resolve the CDS views to their underlying persistence entities, which is only supported for simple projections. +For *read-only* views, you can use the full feature set of [selects](../../cds/cdl#as-select-from), including *joins*, *unions*, and *aggregations*. However, such complex views are not writable and require a schema redeployment if the view definition is changed. +To [write data](#updatable-views) or [delete](#delete-via-view) through views, only use simple [projections](../../cds/cdl#as-projection-on). The CAP Java runtime attempts to resolve the CDS views to their underlying persistence entities, rewriting the statement and data accordingly, which is not supported for complex views. + +For simple projections the generation of SQL views can be avoided by using [runtime views](#runtimeviews). This allows you to change the view definition without redeploying the database schema and is the prerequisite for lightweight extensibility via predefined extension fields. + +::: tip Indicate read-only +Use the `@readonly` annotation to indicate that a view or a view element is not writable. +::: +::: tip Prefer simple views +Prefer creating multiple simple views, each tailored to a specific use case, rather than a single complex view that tries to address multiple use cases simultaneously. +::: ::: warning Avoid selecting to-many Associations Do not use [*to-many associations*](../../cds/cdl#to-many-associations) in the select clause of CDS views. This blocks write operations and may cause performance issues due to record duplication on read. ::: @@ -311,12 +321,7 @@ To add or update CDS views without redeploying the database schema, annotate the Runtime views must be simple [projections](../../cds/cdl#as-projection-on), not using *aggregations*, *join*, *union* or *subqueries* in the *from* clause, but may have a *where* condition if they are only used to read. On write, the restrictions for [write through views](#updatable-views) apply in the same way as for standard CDS views. However, if a runtime view cannot be resolved, a fallback to database views is not possible, and the statement fails with an error. -CAP Java supports two modes for resolving runtime views on read: -- `cte` -- `resolve` - - -In the following section about `cte` and `resolve` we use the following CDS model and query as example: +CAP Java provides two modes for resolving runtime views during read operations: [cte](#rtview-cte) and [resolve](#rtview-resolve). The following section introduces both modes using the CDS model and query below: ```cds entity Books { @@ -337,7 +342,7 @@ SELECT from BooksWithLowStock where author = 'Kafka' #### Read in `cte` mode { #rtview-cte } -This is the default mode in CAP Java `4.x`. The runtime translates the view definition into a _Common Table Expression_ (CTE) and sends it with the query to the database. +This is the default mode in CAP Java `4.x`. The runtime translates the [view definition](#runtimeviews) into a _Common Table Expression_ (CTE) and sends it with the query to the database. ```sql WITH BOOKSWITHLOWSTOCK_CTE AS ( @@ -363,7 +368,7 @@ Enable *cte* mode with *cds.sql.runtimeView.mode: cte* #### Read in `resolve` mode { #rtview-resolve } -The runtime _resolves_ the view definition to the underlying persistence entities and executes the query directly against the corresponding tables. +The runtime _resolves_ the [view definition](#runtimeviews) to the underlying persistence entities and executes the query directly against the corresponding tables. ```sql SELECT B.ID, B.TITLE, A.NAME AS "author" From fbae44036a8ffe231710f3e9ac821660cebf9244 Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Fri, 27 Jun 2025 17:02:24 +0200 Subject: [PATCH 19/31] Pessimistic Locking --- java/working-with-cql/query-execution.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 1b438e3c82..d599d65541 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -358,10 +358,6 @@ SELECT ID, TITLE, AUTHOR AS "author" WHERE A.NAME = ? ``` -::: info Limitations of `cte` mode -[Pessimistic locking](#pessimistic-locking) queries on runtime views in *cte* mode are not supported on SAP HANA. -::: - ::: tip CAP Java 3.10 Enable *cte* mode with *cds.sql.runtimeView.mode: cte* ::: @@ -380,6 +376,9 @@ SELECT B.ID, B.TITLE, A.NAME AS "author" ::: info Limitations of `resolve` mode Using associations that are only [defined](../../cds/cql#association-definitions) in the view, as well as complex draft queries are not supported in *resolve* mode. ::: +::: info Pessimistic Locking on PostgreSQL +On PostgreSQL, some [pessimistic locking](#pessimistic-locking) queries on runtime views navigating associations require the *cte* mode. +::: ### Draft Queries on Views { #draft-views } From 588b41f2639395dc952f0d70d8b51a1700fb6eb5 Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Fri, 27 Jun 2025 18:26:19 +0200 Subject: [PATCH 20/31] Update query-execution.md --- java/working-with-cql/query-execution.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index d599d65541..7112574e8a 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -227,20 +227,22 @@ long deleteCount = service.run(delete).rowCount(); With CDS [views](../../cds/cdl#views-projections) you can derive new entities from existing ones, for example to rename or exclude certain elements, or to add [virtual elements](../../cds/cdl#virtual-elements-in-views) for specific use cases. +::: tip Prefer simple views +Prefer creating multiple simple views, each tailored to a specific use case, rather than a single complex view that tries to address multiple use cases simultaneously. +::: + The CDS compiler generates [DDL](../../guides/databases?impl-variant=java#generating-sql-ddl) files from your CDS model, including SQL views for the CDS views. These views are deployed to the [database](../cqn-services/persistence-services#database-support) and used by the CAP runtime to read data. For *read-only* views, you can use the full feature set of [selects](../../cds/cdl#as-select-from), including *joins*, *unions*, and *aggregations*. However, such complex views are not writable and require a schema redeployment if the view definition is changed. -To [write data](#updatable-views) or [delete](#delete-via-view) through views, only use simple [projections](../../cds/cdl#as-projection-on). The CAP Java runtime attempts to resolve the CDS views to their underlying persistence entities, rewriting the statement and data accordingly, which is not supported for complex views. - -For simple projections the generation of SQL views can be avoided by using [runtime views](#runtimeviews). This allows you to change the view definition without redeploying the database schema and is the prerequisite for lightweight extensibility via predefined extension fields. - ::: tip Indicate read-only Use the `@readonly` annotation to indicate that a view or a view element is not writable. ::: -::: tip Prefer simple views -Prefer creating multiple simple views, each tailored to a specific use case, rather than a single complex view that tries to address multiple use cases simultaneously. -::: + +To [write data](#updatable-views) or [delete](#delete-via-view) through views, only use simple [projections](../../cds/cdl#as-projection-on). The CAP Java runtime attempts to resolve the CDS views to their underlying persistence entities, rewriting the statement and data accordingly, which is not supported for complex views. + +For simple projections, the generation of SQL views can be avoided by using [runtime views](#runtimeviews). This allows you to change the view definition without redeploying the database schema and is the prerequisite for lightweight extensibility via predefined extension fields. + ::: warning Avoid selecting to-many Associations Do not use [*to-many associations*](../../cds/cdl#to-many-associations) in the select clause of CDS views. This blocks write operations and may cause performance issues due to record duplication on read. ::: From c3fc509420cc161e4dad6e69dc78e354eecd3228 Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Mon, 30 Jun 2025 14:19:58 +0200 Subject: [PATCH 21/31] RT view config option and hint --- java/working-with-cql/query-execution.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 7112574e8a..0b2e73ad1e 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -323,7 +323,17 @@ To add or update CDS views without redeploying the database schema, annotate the Runtime views must be simple [projections](../../cds/cdl#as-projection-on), not using *aggregations*, *join*, *union* or *subqueries* in the *from* clause, but may have a *where* condition if they are only used to read. On write, the restrictions for [write through views](#updatable-views) apply in the same way as for standard CDS views. However, if a runtime view cannot be resolved, a fallback to database views is not possible, and the statement fails with an error. -CAP Java provides two modes for resolving runtime views during read operations: [cte](#rtview-cte) and [resolve](#rtview-resolve). The following section introduces both modes using the CDS model and query below: +CAP Java provides two modes for resolving runtime views during read operations: [cte](#rtview-cte) and [resolve](#rtview-resolve). + +::: details Set the runtime view mode +Set *cds.sql.runtimeView.mode* with value *cte* or *resolve* to globally set the runtime view mode, use a query [hint](#hana-hints) to set the mode for a specific query: + +```Java +Select.from(BooksWithLowStock).hint("cds.sql.runtimeView.mode", "cte"); +``` +::: + +The following section introduces both modes using the CDS model and query below: ```cds entity Books { From a203b03982aa33a669fc6498697f36ed71d235ff Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Mon, 30 Jun 2025 14:36:39 +0200 Subject: [PATCH 22/31] annotation --- java/working-with-cql/query-execution.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 0b2e73ad1e..e28d1681c1 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -326,7 +326,9 @@ Runtime views must be simple [projections](../../cds/cdl#as-projection-on), not CAP Java provides two modes for resolving runtime views during read operations: [cte](#rtview-cte) and [resolve](#rtview-resolve). ::: details Set the runtime view mode -Set *cds.sql.runtimeView.mode* with value *cte* or *resolve* to globally set the runtime view mode, use a query [hint](#hana-hints) to set the mode for a specific query: +To globally set the runtime view mode, use the property `cds.sql.runtimeView.mode` with value `cte` or `resolve` in the *application.yml*. To set the mode for a specific runtime view, annotate it with `@cds.java.runtimeView.mode: cte|resolve`. + +To set the mode for a specific query, use a [hint](#hana-hints): ```Java Select.from(BooksWithLowStock).hint("cds.sql.runtimeView.mode", "cte"); From 1a5e13c71426e741caa26d74e378b446017698ab Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Mon, 30 Jun 2025 14:38:36 +0200 Subject: [PATCH 23/31] Update query-execution.md --- java/working-with-cql/query-execution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index e28d1681c1..a1c6367cab 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -325,7 +325,7 @@ Runtime views must be simple [projections](../../cds/cdl#as-projection-on), not CAP Java provides two modes for resolving runtime views during read operations: [cte](#rtview-cte) and [resolve](#rtview-resolve). -::: details Set the runtime view mode +::: details Changing the runtime view mode To globally set the runtime view mode, use the property `cds.sql.runtimeView.mode` with value `cte` or `resolve` in the *application.yml*. To set the mode for a specific runtime view, annotate it with `@cds.java.runtimeView.mode: cte|resolve`. To set the mode for a specific query, use a [hint](#hana-hints): From f2097ea9f5b960a911c63f7a543c1c1bc37f8e05 Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Thu, 3 Jul 2025 13:04:54 +0200 Subject: [PATCH 24/31] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Adrian Görler --- java/working-with-cql/query-execution.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index a1c6367cab..7bdbd3dbab 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -231,7 +231,7 @@ With CDS [views](../../cds/cdl#views-projections) you can derive new entities fr Prefer creating multiple simple views, each tailored to a specific use case, rather than a single complex view that tries to address multiple use cases simultaneously. ::: -The CDS compiler generates [DDL](../../guides/databases?impl-variant=java#generating-sql-ddl) files from your CDS model, including SQL views for the CDS views. These views are deployed to the [database](../cqn-services/persistence-services#database-support) and used by the CAP runtime to read data. +From the CDS model the CDS compiler generates [DDL](../../guides/databases?impl-variant=java#generating-sql-ddl) files, which include SQL views for the CDS views. These views are deployed to the [database](../cqn-services/persistence-services#database-support) and used by the CAP runtime to read data. For *read-only* views, you can use the full feature set of [selects](../../cds/cdl#as-select-from), including *joins*, *unions*, and *aggregations*. However, such complex views are not writable and require a schema redeployment if the view definition is changed. @@ -282,7 +282,7 @@ UPDATE entity OrderView2 ``` - Data for elements corresponding to *expressions* and *functions* (*country*) is ignored. - [Deep write](./query-execution#deep-insert-upsert) via (aliased) compositions (*lineItems*) is supported if there are corresponding compositions (*items*) in the underlying entity definition. Deep write via compositions that are only defined in the view (for example via [mixins](../../cds/cql#association-definitions)) is not supported and the data is ignored. -- [Path expressions](../../cds/cql#path-expressions) over compositions (*header.status*) are writable. For [Inserts](./query-api#insert), the view must expose all *not null* elements of the target entity and the data must include values for all of them. In the example above, the order header must have a generated key to support inserting new orders with a value for *headerStatus*. +- [Path expressions](../../cds/cql#path-expressions) over compositions *of one* (*header.status*) are writable. For [Inserts](./query-api#insert), the view must expose all *not null* elements of the target entity and the data must include values for all of them. In the example above, the order header must have a generated key to support inserting new orders with a value for *headerStatus*. ::: warning Path Expressions over Associations Path expressions navigating *associations* (*header.customer.name*) are [not writable](#cascading-over-associations) by default. To avoid issues on write, annotate them with [@readonly](../../guides/providing-services#readonly). @@ -326,12 +326,12 @@ Runtime views must be simple [projections](../../cds/cdl#as-projection-on), not CAP Java provides two modes for resolving runtime views during read operations: [cte](#rtview-cte) and [resolve](#rtview-resolve). ::: details Changing the runtime view mode -To globally set the runtime view mode, use the property `cds.sql.runtimeView.mode` with value `cte` or `resolve` in the *application.yml*. To set the mode for a specific runtime view, annotate it with `@cds.java.runtimeView.mode: cte|resolve`. +To globally set the runtime view mode, use the property `cds.sql.runtimeView.mode` with value `cte` (the default) or `resolve` in the *application.yml*. To set the mode for a specific runtime view, annotate it with `@cds.java.runtimeView.mode: cte|resolve`. To set the mode for a specific query, use a [hint](#hana-hints): ```Java -Select.from(BooksWithLowStock).hint("cds.sql.runtimeView.mode", "cte"); +Select.from(BooksWithLowStock).hint("cds.sql.runtimeView.mode", "resolve"); ``` ::: @@ -356,7 +356,7 @@ SELECT from BooksWithLowStock where author = 'Kafka' #### Read in `cte` mode { #rtview-cte } -This is the default mode in CAP Java `4.x`. The runtime translates the [view definition](#runtimeviews) into a _Common Table Expression_ (CTE) and sends it with the query to the database. +This is the default mode since CAP Java `4.x`. The runtime translates the [view definition](#runtimeviews) into a _Common Table Expression_ (CTE) and sends it with the query to the database. ```sql WITH BOOKSWITHLOWSTOCK_CTE AS ( From 2f1a1c5b37fc5baa0431df10ad9f34ee2f931049 Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Thu, 3 Jul 2025 13:41:55 +0200 Subject: [PATCH 25/31] Review Comments --- java/working-with-cql/query-execution.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 7bdbd3dbab..23a7d576c7 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -227,24 +227,23 @@ long deleteCount = service.run(delete).rowCount(); With CDS [views](../../cds/cdl#views-projections) you can derive new entities from existing ones, for example to rename or exclude certain elements, or to add [virtual elements](../../cds/cdl#virtual-elements-in-views) for specific use cases. -::: tip Prefer simple views -Prefer creating multiple simple views, each tailored to a specific use case, rather than a single complex view that tries to address multiple use cases simultaneously. -::: - From the CDS model the CDS compiler generates [DDL](../../guides/databases?impl-variant=java#generating-sql-ddl) files, which include SQL views for the CDS views. These views are deployed to the [database](../cqn-services/persistence-services#database-support) and used by the CAP runtime to read data. For *read-only* views, you can use the full feature set of [selects](../../cds/cdl#as-select-from), including *joins*, *unions*, and *aggregations*. However, such complex views are not writable and require a schema redeployment if the view definition is changed. -::: tip Indicate read-only -Use the `@readonly` annotation to indicate that a view or a view element is not writable. +::: warning Annotate read-only views and elements +Use the `@readonly` annotation to indicate that a view or a view element is not writable, as this is not automatically detected by the CDS compiler. ::: To [write data](#updatable-views) or [delete](#delete-via-view) through views, only use simple [projections](../../cds/cdl#as-projection-on). The CAP Java runtime attempts to resolve the CDS views to their underlying persistence entities, rewriting the statement and data accordingly, which is not supported for complex views. -For simple projections, the generation of SQL views can be avoided by using [runtime views](#runtimeviews). This allows you to change the view definition without redeploying the database schema and is the prerequisite for lightweight extensibility via predefined extension fields. +For simple [projections](../../cds/cdl#as-projection-on), the generation of SQL views can be avoided by using [runtime views](#runtimeviews). This allows you to change the view definition without redeploying the database schema and is the prerequisite for lightweight extensibility via predefined extension fields. -::: warning Avoid selecting to-many Associations -Do not use [*to-many associations*](../../cds/cdl#to-many-associations) in the select clause of CDS views. This blocks write operations and may cause performance issues due to record duplication on read. +::: tip Prefer simple views +Prefer creating multiple simple views, each tailored to a specific use case, rather than a single complex view that tries to address multiple use cases simultaneously. +::: +::: warning Avoid selecting paths over to-many Associations +Do not use [path expressions](../../cds/cql#path-expressions-in-all-other-clauses) over [*to-many associations*](../../cds/cdl#to-many-associations) in the select clause of CDS views. This blocks write operations and may cause performance issues due to record duplication on read. ::: ::: warning Avoid Composition Definitions in Views Avoid [defining](../../cds/cql#association-definitions) new *compositions* in CDS views and prefer *associations* instead, as [deep write](#updatable-views) and [cascading delete](#delete-via-view) are only supported for compositions in persistence entities. @@ -319,7 +318,7 @@ The delete operation is resolved to the underlying `Order` entity with ID *42* a ### Runtime Views { #runtimeviews } -To add or update CDS views without redeploying the database schema, annotate them with [@cds.persistence.skip](../../guides/databases#cds-persistence-skip). This tells the CDS compiler to skip generating database views for these CDS views, and the CAP Java runtime resolves them dynamically on each request. +To add or update CDS views without redeploying the database schema, annotate them with [@cds.persistence.skip](../../guides/databases#cds-persistence-skip). This advises the CDS compiler to skip generating database views for these CDS views. Instead, CAP Java resolves them *at runtime* on each request. Runtime views must be simple [projections](../../cds/cdl#as-projection-on), not using *aggregations*, *join*, *union* or *subqueries* in the *from* clause, but may have a *where* condition if they are only used to read. On write, the restrictions for [write through views](#updatable-views) apply in the same way as for standard CDS views. However, if a runtime view cannot be resolved, a fallback to database views is not possible, and the statement fails with an error. From bc2e868987238d6a0cf2d892bcbee6e7b5bb5c38 Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Thu, 3 Jul 2025 14:05:07 +0200 Subject: [PATCH 26/31] read-only views --- java/working-with-cql/query-execution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 23a7d576c7..97ad0ca189 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -229,7 +229,7 @@ With CDS [views](../../cds/cdl#views-projections) you can derive new entities fr From the CDS model the CDS compiler generates [DDL](../../guides/databases?impl-variant=java#generating-sql-ddl) files, which include SQL views for the CDS views. These views are deployed to the [database](../cqn-services/persistence-services#database-support) and used by the CAP runtime to read data. -For *read-only* views, you can use the full feature set of [selects](../../cds/cdl#as-select-from), including *joins*, *unions*, and *aggregations*. However, such complex views are not writable and require a schema redeployment if the view definition is changed. +For *read-only* views, you can use the full feature set of [selects](../../cds/cdl#as-select-from), including *aggregations* to summarize, as well as *joins* and *unions* to combine data from multiple entities. However, such complex views are *not writable* and require a schema redeployment if the view definition is changed. ::: warning Annotate read-only views and elements Use the `@readonly` annotation to indicate that a view or a view element is not writable, as this is not automatically detected by the CDS compiler. From cd9cce83c1ee070e171d168f9b08387543122271 Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Thu, 3 Jul 2025 17:25:31 +0200 Subject: [PATCH 27/31] Review suggestion --- java/working-with-cql/query-execution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 97ad0ca189..c3f22727b0 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -245,7 +245,7 @@ Prefer creating multiple simple views, each tailored to a specific use case, rat ::: warning Avoid selecting paths over to-many Associations Do not use [path expressions](../../cds/cql#path-expressions-in-all-other-clauses) over [*to-many associations*](../../cds/cdl#to-many-associations) in the select clause of CDS views. This blocks write operations and may cause performance issues due to record duplication on read. ::: -::: warning Avoid Composition Definitions in Views +::: Avoid composition definitions in views Avoid [defining](../../cds/cql#association-definitions) new *compositions* in CDS views and prefer *associations* instead, as [deep write](#updatable-views) and [cascading delete](#delete-via-view) are only supported for compositions in persistence entities. ::: From f8eeae2cb00028d1987d7f8d7d34e8832ffedc2f Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Thu, 3 Jul 2025 17:29:47 +0200 Subject: [PATCH 28/31] warning --- java/working-with-cql/query-execution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index c3f22727b0..bdeec41002 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -245,7 +245,7 @@ Prefer creating multiple simple views, each tailored to a specific use case, rat ::: warning Avoid selecting paths over to-many Associations Do not use [path expressions](../../cds/cql#path-expressions-in-all-other-clauses) over [*to-many associations*](../../cds/cdl#to-many-associations) in the select clause of CDS views. This blocks write operations and may cause performance issues due to record duplication on read. ::: -::: Avoid composition definitions in views +::: warning Avoid composition definitions in views Avoid [defining](../../cds/cql#association-definitions) new *compositions* in CDS views and prefer *associations* instead, as [deep write](#updatable-views) and [cascading delete](#delete-via-view) are only supported for compositions in persistence entities. ::: From f0629acc3c57012742c3694ff790f4cc0be74026 Mon Sep 17 00:00:00 2001 From: Rene Jeglinsky Date: Fri, 4 Jul 2025 06:16:44 +0200 Subject: [PATCH 29/31] edit --- java/working-with-cql/query-execution.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 97ad0ca189..8c5a33304f 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -124,7 +124,7 @@ To add a hint clause to a statement, use the `hints` method and prefix the [SAP ```java Select.from(BOOKS).hints("hdb.USE_HEX_PLAN", "hdb.ESTIMATION_SAMPLES(0)"); ``` -::: warning +::: warning No external input in SQL for SAP HANA Hints prefixed with `hdb.` are directly rendered into SQL for SAP HANA and therefore **must not** contain external input! ::: @@ -156,7 +156,7 @@ long rowCount = service.run(update).rowCount(); If no rows are touched the execution is successful but the row count is 0. -:::warning +:::warning Update with expressions The setters of an [update with expressions](../working-with-cql/query-api#update-expressions) are evaluated on the database. The result of these expressions is not contained in the update result. ::: @@ -167,7 +167,8 @@ It's possible to work with structured data as the insert, update, and delete ope #### Cascading over Associations { #cascading-over-associations} By default, *insert*, *update* and *delete* operations cascade over [compositions](../../guides/domain-modeling#compositions) only. For associations, this can be enabled using the `@cascade` annotation. -::: warning + +::: warning Avoid cascading over associations Cascading operations over associations isn't considered good practice and should be avoided. ::: @@ -189,12 +190,10 @@ entity Author { } ``` -::: warning _❗ Warning_ -For inactive draft entities `@cascade` annotations are ignored. -::: +::: warning _Warning_ +- For inactive draft entities `@cascade` annotations are ignored. -::: warning _❗ Warning_ -The @cascade annotation is not respected by foreign key constraints on the database. To avoid unexpected behaviour you might have to disable a FK constraint with [`@assert.integrity:false`](../../guides/databases#database-constraints). +- The `@cascade` annotation is not respected by foreign key constraints on the database. To avoid unexpected behaviour you might have to disable a foreign key constraint with [`@assert.integrity:false`](../../guides/databases#database-constraints). ::: #### Deep Insert / Upsert { #deep-insert-upsert} @@ -251,7 +250,7 @@ Avoid [defining](../../cds/cql#association-definitions) new *compositions* in CD ### Write through Views { #updatable-views } -You can run [Insert](./query-api#insert), [Upsert](./query-api#upsert), and [Update](./query-api#update) statements on CDS views that are writable on the database or can be resolved to a single persistence entity by the CAP Java runtime. +You can run [insert](./query-api#insert), [upsert](./query-api#upsert), and [update](./query-api#update) statements on CDS views that are writable on the database or can be resolved to a single persistence entity by the CAP Java runtime. CDS views must fulfill the following requirements to be resolvable: @@ -281,7 +280,7 @@ UPDATE entity OrderView2 ``` - Data for elements corresponding to *expressions* and *functions* (*country*) is ignored. - [Deep write](./query-execution#deep-insert-upsert) via (aliased) compositions (*lineItems*) is supported if there are corresponding compositions (*items*) in the underlying entity definition. Deep write via compositions that are only defined in the view (for example via [mixins](../../cds/cql#association-definitions)) is not supported and the data is ignored. -- [Path expressions](../../cds/cql#path-expressions) over compositions *of one* (*header.status*) are writable. For [Inserts](./query-api#insert), the view must expose all *not null* elements of the target entity and the data must include values for all of them. In the example above, the order header must have a generated key to support inserting new orders with a value for *headerStatus*. +- [Path expressions](../../cds/cql#path-expressions) over compositions *of one* (*header.status*) are writable. For [inserts](./query-api#insert), the view must expose all *not null* elements of the target entity and the data must include values for all of them. In the example above, the order header must have a generated key to support inserting new orders with a value for *headerStatus*. ::: warning Path Expressions over Associations Path expressions navigating *associations* (*header.customer.name*) are [not writable](#cascading-over-associations) by default. To avoid issues on write, annotate them with [@readonly](../../guides/providing-services#readonly). @@ -289,7 +288,7 @@ UPDATE entity OrderView2 ### Delete through Views { #delete-via-view } -The CAP Java runtime attempts to resolve [Deletes](./query-api#delete) on CDS views to the underlying persistence entity definitions and the [write through views](#updatable-views) restrictions apply accordingly. +The CAP Java runtime attempts to resolve [deletes](./query-api#delete) on CDS views to the underlying persistence entity definitions and the [write through views](#updatable-views) restrictions apply accordingly. If a view cannot be resolved, the delete operation is executed directly on the database view and the execution depends on the [database](../cqn-services/persistence-services#database-support) support. From de7ff1e94d5e025509ccd6cdea01d3769bc12ccc Mon Sep 17 00:00:00 2001 From: Rene Jeglinsky Date: Fri, 4 Jul 2025 07:02:47 +0200 Subject: [PATCH 30/31] edit --- java/working-with-cql/query-execution.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 3a74d10bf5..f226465cbc 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -292,7 +292,7 @@ The CAP Java runtime attempts to resolve [deletes](./query-api#delete) on CDS vi If a view cannot be resolved, the delete operation is executed directly on the database view and the execution depends on the [database](../cqn-services/persistence-services#database-support) support. -::: danger Delete Cascades on Persistence Entity Level +::: danger Delete cascades on persistence entity level [Cascading delete](./query-execution#cascading-delete) is applied on persistence entity level only, including compositions that are excluded from the view. Compositions that are [added](../../cds/cql#association-definitions) in CDS views, as well as changes to compositions (such as filters and redirects) are not considered. ::: @@ -388,7 +388,7 @@ SELECT B.ID, B.TITLE, A.NAME AS "author" ::: info Limitations of `resolve` mode Using associations that are only [defined](../../cds/cql#association-definitions) in the view, as well as complex draft queries are not supported in *resolve* mode. ::: -::: info Pessimistic Locking on PostgreSQL +::: info Pessimistic locking on PostgreSQL On PostgreSQL, some [pessimistic locking](#pessimistic-locking) queries on runtime views navigating associations require the *cte* mode. ::: @@ -404,21 +404,21 @@ That means: Remember to run draft specific queries through the [Draft Service](../fiori-drafts#draftservices) or [Application Service](../cqn-services/application-services#application-services). The [Persistence Service](../cqn-services/persistence-services) only works for non-draft specific queries. -::: tip Draft Queries on Runtime Views +::: tip Draft queries on runtime views If you define runtime views on [draft-enabled](../fiori-drafts#reading-drafts) entities and want to run draft specific queries on these views, set the [*cds.drafts.persistence*](../fiori-drafts#reading-drafts) configuration to `split`. ::: -::: warning Avoid draft-enabling Runtime Views +::: warning Avoid draft-enabling runtime views Draft-enabling runtime views is only supported in [*CTE*](#rtview-cte) mode and requires a schema deployment to update the draft table when the runtime view is changed. ::: ### Views on Remote Services -When delegating queries between Application Services and Remote Services, statements are resolved to the targeted service's entity definitions by the CAP Java runtime. +When delegating queries between Application Services and Remote Services, statements are resolved to the targeted service's entity definition by the CAP Java runtime. -For read, the CDS views are resolved similar to the runtime view [resolve](#rtview-resolve) mode. For write operations, views targeting *remote OData* services must +For read, the CDS views are resolved similar to the runtime view [resolve](#rtview-resolve) mode. For write operations, views targeting *remote OData* services must fulfill the following: -- fulfill all requirements of [writable views](#updatable-views) +- all requirements of [writable views](#updatable-views) - not include [calculated elements](../../cds/cdl#calculated-elements) If a view cannot be resolved, read and write operations are rejected. From b007451edcee6dc95c37ecf02ad7dde562ca214e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Jeglinsky?= Date: Fri, 4 Jul 2025 12:30:58 +0200 Subject: [PATCH 31/31] Update java/working-with-cql/query-execution.md --- java/working-with-cql/query-execution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index f226465cbc..0ef628faac 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -333,7 +333,7 @@ Select.from(BooksWithLowStock).hint("cds.sql.runtimeView.mode", "resolve"); ``` ::: -The following section introduces both modes using the CDS model and query below: +The next two sections introduce both modes using the following CDS model and query: ```cds entity Books {