-
Notifications
You must be signed in to change notification settings - Fork 131
Java: Views and Projections #1916
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 21 commits
9c8d82c
75a0bca
aab143d
9bc4262
f5b71c9
f937dcb
502a2ab
c421e25
6ddfb0b
5bf74f2
b30d427
a0d97be
f164810
67573ef
579b93a
28d0423
b79db42
e2e7751
c2af4ef
fbae440
588b41f
c3fc509
a203b03
1a5e13c
f2097ea
2f1a1c5
bc2e868
cd9cce8
f8eeae2
f0629ac
ffb1497
de7ff1e
b007451
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -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,202 @@ 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. | ||||||||||
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. | ||||||||||
|
||||||||||
Views and projections can be resolved if the following conditions are met: | ||||||||||
::: 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. | ||||||||||
::: | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this rather belongs to the best practices |
||||||||||
|
||||||||||
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. | ||||||||||
MattSchur marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
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. | ||||||||||
MattSchur marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
::: tip Indicate read-only | ||||||||||
Use the `@readonly` annotation to indicate that a view or a view element is not writable. | ||||||||||
::: | ||||||||||
MattSchur marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
- The view definition does not use any other clause than `columns` and `excluding`. | ||||||||||
- 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. | ||||||||||
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. | ||||||||||
agoerler marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
::: 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. | ||||||||||
MattSchur marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
::: | ||||||||||
::: warning Avoid Composition Definitions in Views | ||||||||||
MattSchur marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
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. | ||||||||||
MattSchur marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not about avoiding cascading over associations but deep write and cascade delete are not supported by the runtime for such compositions and would need to be handled by custom code. |
||||||||||
::: | ||||||||||
|
||||||||||
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`. | ||||||||||
### 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. | ||||||||||
MattSchur marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
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 | ||||||||||
// 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 }; | ||||||||||
MattSchur marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
// 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 | ||||||||||
MattSchur marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
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*. | ||||||||||
MattSchur marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
::: 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). | ||||||||||
MattSchur marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
::: | ||||||||||
|
||||||||||
### 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. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Has this ever been sucessful? Or do we just get worse error messages? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably rather the latter - we could skip the fallback |
||||||||||
|
||||||||||
::: 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. | ||||||||||
agoerler marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
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. | ||||||||||
- 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. | ||||||||||
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. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Runtime views may use only CDS QL, which is supported by the CAP Java runtime. Joins and unions are not supported. We have more restrictions in the "resolve" mode. The "cte" mode is more powerful. |
||||||||||
|
||||||||||
Example of a view that can't be resolved: | ||||||||||
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 | ||||||||||
// 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 }; | ||||||||||
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; // makes the view read only | ||||||||||
``` | ||||||||||
```sql | ||||||||||
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. | ||||||||||
MattSchur marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
```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 3.10 | ||||||||||
MattSchur marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
Enable *cte* mode with *cds.sql.runtimeView.mode: cte* | ||||||||||
::: | ||||||||||
|
||||||||||
#### Read in `resolve` mode { #rtview-resolve } | ||||||||||
|
||||||||||
The runtime _resolves_ the [view definition](#runtimeviews) to the underlying persistence entities and executes the query directly against the corresponding tables. | ||||||||||
|
||||||||||
```sql | ||||||||||
vmikhailenko marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
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 = ? | ||||||||||
``` | ||||||||||
|
||||||||||
::: 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. | ||||||||||
::: | ||||||||||
|
||||||||||
MattSchur marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
### 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. | ||||||||||
|
||||||||||
That means: | ||||||||||
<br> | ||||||||||
-> [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#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 | ||||||||||
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 | ||||||||||
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. | ||||||||||
|
||||||||||
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 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. | ||||||||||
|
||||||||||
|
||||||||||
## 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 +557,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 +701,7 @@ Map<String, String> 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. | ||||||||||
|
||||||||||
|
Uh oh!
There was an error while loading. Please reload this page.