From 0b81c2fcb4764c4dd0ec4b3173c11a8cf200641c Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Tue, 27 May 2025 15:08:23 +0200 Subject: [PATCH 1/5] Runtime Views: `CTE` mode --- java/working-with-cql/query-execution.md | 64 ++++++++++++++++-------- 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 8f206e176..ac31fe9f8 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -400,11 +400,17 @@ 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} +## Runtime Views { #runtimeviews } -The CDS compiler generates [SQL DDL](../../guides/databases?impl-variant=java#generating-sql-ddl) statements based on your CDS model, which include SQL views for all CDS [views and projections](../../cds/cdl#views-projections). This means adding or changing CDS views requires a deployment of the database schema changes. +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 updates due to adding or updating CDS views, annotate them with [@cds.persistence.skip](../../guides/databases#cds-persistence-skip). In this case the CDS compiler won't generate corresponding static database views. Instead, the CDS views are dynamically resolved by the CAP Java runtime. +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 static database views for these entities. Instead, the CAP Java runtime dynamically resolves such views at query time. + +::: 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`. +::: + +For example, consider the following CDS model and query: ```cds entity Books { @@ -413,33 +419,47 @@ entity Books { stock : Integer; author : Association to one Authors; } -@cds.persistence.skip // [!code focus] -entity BooksWithLowStock as projection on Books { // [!code focus] - id, title, author.name as author // [!code focus] -} where stock < 10; // [!code focus] +@cds.persistence.skip +entity BooksWithLowStock as projection on Books { + id, title, author.name as author +} where stock < 10; ``` - -At runtime, CAP Java resolves queries against runtime views until an entity is reached that isn't annotated with *@cds.persistence.skip*. For example, the CQL query - ```sql Select BooksWithLowStock where author = 'Kafka' ``` -is executed against SQL databases as - -```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 = ? -``` +CAP Java provides two modes for resolving runtime views: -::: warning Limitations -Runtime views are supported for simple [CDS projections](../../cds/cdl#as-projection-on). Expands of [filtered associations](../../cds/cdl#publish-associations-with-filter) are only supported since `3.7.0`. Constant values and expressions in runtime views are supported since `3.8.0`. +**`cte` mode**: The runtime translates the view definition into a Common Table Expression (CTE) and sends it with the query to the database. -Complex views using aggregations or union/join/subqueries in `FROM` are not supported and for reading [draft-enabled](../fiori-drafts#reading-drafts) entities, `cds.drafts.persistence` needs to be set to `split`. +```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 uses `cte` mode by default. In 3.10, enable it with **cds.sql.runtimeView.mode: cte**. ::: -### Using I/O Streams in Queries +**`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 As described in section [Predefined Types](../cds-data#predefined-types) it's possible to stream the data, if the element is annotated with `@Core.MediaType`. The following example demonstrates how to allocate the stream for element `coverImage`, pass it through the API to an underlying database and close the stream. @@ -473,7 +493,7 @@ try (InputStream resource = getResource("IMAGE.PNG")) { // Transaction finished ``` -### Using Native SQL +## Using Native SQL CAP Java doesn't have a dedicated API to execute native SQL Statements. However, when using Spring as application framework you can leverage Spring's features to execute native SQL statements. See [Execute SQL statements with Spring's JdbcTemplate](../cqn-services/persistence-services#jdbctemplate) for more details. From c596559fba1968ae35a779274a57433af44d8905 Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Tue, 27 May 2025 16:11:04 +0200 Subject: [PATCH 2/5] Migration guide: Add property --- java/migration.md | 1 + 1 file changed, 1 insertion(+) diff --git a/java/migration.md b/java/migration.md index 16431d2d5..c64577e20 100644 --- a/java/migration.md +++ b/java/migration.md @@ -98,6 +98,7 @@ Some property defaults have been adjusted: | `cds.security.authorization.instanceBased.rejectSelectedUnauthorizedEntity.enabled` | false | true | Requests that violate instance-based authorization conditions now fail with 403, instead of 404. | | `cds.security.authorization.instanceBased.checkInputData.enabled` | false | true | [Authorization Checks On Input Data](./security#input-data-auth) are now enabled by default. | | `cds.errors.defaultTranslations.enabled` | false | true | [Translations for Validation Error Messages](./event-handlers/indicating-errors#ootb-translated-messages) are now enabled by default. | +| `cds.sql.runtimeView.mode` | resolve | cte | [Runtime views](./working-with-cql/query-execution#runtimeviews) are now by default translated into Common Table Expressions | ### Deprecated Properties From ba56a3f9bc9ed0073a9ff1d962ce7628b0b806ce Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Wed, 28 May 2025 08:52:13 +0200 Subject: [PATCH 3/5] No calculated elements --- 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 ac31fe9f8..3565073e5 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -407,7 +407,7 @@ The CDS compiler generates [SQL DDL](../../guides/databases?impl-variant=java#ge 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 static database views for these entities. Instead, the CAP Java runtime dynamically resolves such views at query time. ::: 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`. +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: From ad9f2696d95724aad9798fc8b1ef9713fd0e0c80 Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Wed, 28 May 2025 08:56:20 +0200 Subject: [PATCH 4/5] 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 3565073e5..c5903cc26 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -407,7 +407,7 @@ The CDS compiler generates [SQL DDL](../../guides/databases?impl-variant=java#ge 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 static database views for these entities. Instead, the CAP Java runtime dynamically resolves such views at query time. ::: 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. +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: From 2e8d0f25315b6ee4625f2edd699f2ad95b474aca Mon Sep 17 00:00:00 2001 From: Matthias Schur <107557548+MattSchur@users.noreply.github.com> Date: Wed, 28 May 2025 14:27:05 +0200 Subject: [PATCH 5/5] 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 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index c5903cc26..af60b19a2 100644 --- a/java/working-with-cql/query-execution.md +++ b/java/working-with-cql/query-execution.md @@ -404,7 +404,7 @@ The parameter `mode` allows to specify whether an `EXCLUSIVE` or a `SHARED` lock 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 static database views for these entities. Instead, the CAP Java runtime dynamically resolves such views at query time. +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. @@ -430,7 +430,7 @@ 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. +**`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 ( @@ -447,10 +447,10 @@ SELECT ID, TITLE, AUTHOR AS "author" ``` ::: tip -CAP Java 4 uses `cte` mode by default. In 3.10, enable it with **cds.sql.runtimeView.mode: cte**. +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. +**`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"