diff --git a/java/migration.md b/java/migration.md index 21fa59e07..1697c152b 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 diff --git a/java/working-with-cql/query-execution.md b/java/working-with-cql/query-execution.md index 8f206e176..af60b19a2 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 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 { @@ -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.x 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.