You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: java/working-with-cql/query-api.md
+92-40Lines changed: 92 additions & 40 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1308,30 +1308,73 @@ The Query Builder API supports using expressions in many places. Expressions con
1308
1308
1309
1309
### Entity References {#entity-refs}
1310
1310
1311
-
Entity references specify entity sets. They can be used to define the target entity set of a [CQL](../../cds/cql) statement or be an argument of event handler.
1311
+
Entity references specify entity sets and define the target entity set of a [CQL](../../cds/cql) statement or be an argument of event handler.
1312
1312
1313
-
You can also get [entity references](query-execution#entity-refs)from the result of a CDS QL statement to address an entity via its key values in other statements.
1313
+
Reference consists of _segments_ that define the path from the entity's root to the certain part of it. Each segment has the _identifier_ with the name of the entity or an element and an optional filter _predicate_. These predicates might include other references.
1314
1314
1315
-
Each reference has ordered sequence of _segments_ that define the path from the entity's root to the certain part of it. Segment has the _identifier_ with the name of the entity or an element and optional filter _predicate_.
1315
+
References can be represented in the JSON following an [Expression](../../cds/cxn) notation.
1316
1316
1317
-
Existing reference can be reused as an object or a variable, or a new reference can be built on top of it. References are not bound to the particular model and are not checked against it while they are being built.
1317
+
References are either _absolute_or _relative_. Absolute refs always have fully qualified name of the type in their first segment. Relative references need other absolute reference to which they relate.
1318
1318
1319
-
References can be _absolute_ or _relative_. Absolute reference has fully qualified entity name as the identifier in the first segment. They usually have associations as their segments.
1320
-
1321
-
You start with the reference pointing to a book with certain key. You build it using corresponding [model interfaces](../cqn-services/persistence-services#model-interfaces) providing you the methods that corresponds to the elements of the book.
1319
+
Simplest kind of absolute reference is the reference to the entity set, for example, to all books.
StructuredTypeRef ref = bookWithId.asRef(); // or CqnStructuredTypeRef which is cleaner equivalent type
1328
1325
```
1329
1326
1330
-
This reference is absolute and can be used as the source of the statement or several statements.
1327
+
Method `asRef()` seals the reference and makes it immutable.
1328
+
1329
+
Relative references typically reference elements of the entity, for example, title of the book. They are members of select list of the CQL statement and are relative to its source.
1331
1330
1332
1331
```java
1333
-
importcom.sap.cds.ql.CQL;
1332
+
CqnElementRef title =CQL.entity(Books_.class).title(); // {"ref":["title"]}
New references are constructed with [model interfaces](../cqn-services/persistence-services#model-interfaces) or via API that is also used to build [CQL statements](/java/working-with-cql/query-api#concepts). For most of the application code, the model interfaces are the recommended way to do this.
1337
+
1338
+
References might also represent navigation within the structured entity or between different entities via its associations. For example, below is the reference that represents the path from the book to its chapters.
Each segment of this reference has an identifier (typically an association or composition) and the filter.
1345
+
1346
+
```json
1347
+
{
1348
+
"ref": [
1349
+
{
1350
+
"id": "sap.capire.bookshop.Books",
1351
+
"where": [
1352
+
{ "ref": ["ID"]}, "=", {"val": "..."}
1353
+
]
1354
+
},
1355
+
{
1356
+
"id": "chapters",
1357
+
"where": [
1358
+
{ "ref": ["ID"]}, "=", {"val": "..."}
1359
+
]
1360
+
},
1361
+
{
1362
+
"id": "pages",
1363
+
"where": [
1364
+
{ "ref": ["ID"]}, "=", {"val": "..."}
1365
+
]
1366
+
}
1367
+
]
1368
+
}
1369
+
```
1370
+
1371
+
Existing reference can be reused as an object or a variable, or a new reference can be built on top of it. They can be introspected with [`CqnVisitor`](/java/working-with-cql/query-introspection#cqnvisitor). They are not bound to the particular model and are not checked against it while they are being built.
1372
+
1373
+
Each reference can be serialized as JSON and also renders JSON as its `toString()` implementation. Do not use this JSON to process the references, for example, to extract values from them or to compare references between each other.
1374
+
1375
+
Absolute references can be used as sources of the CQL statements and statements generated by CAP typically have them as their [sources](/java/working-with-cql/query-api#from-reference).
If you want to use this ref to fetch the author of this book, you use `CQL.entity(...)` to make it typed again and add one more segment to it. Note, that this does not check that original ref is indeed the ref to the book, this only lets you use the required model interface.
1389
+
The resulting statement has two references: one absolute describing the author and the one relative, describing the name of the author.
1390
+
1391
+
References can be analyzed with the [`CqnAnalyzer`](/java/working-with-cql/query-introspection#cqnanalyzer) to bind it back to the model, for example, to find annotations or extract filter values.
1392
+
1393
+
The existing references obtained from the statements or [injected in custom handlers](/java/event-handlers/#entity-reference-arguments) can be used to produce new references.
1394
+
1395
+
Given that there is simple reference pointing to the book created as follows.
`CQL.to(...)`lets you use dynamic syntax to express the same.
1402
+
To navigate to author of the book, use `CQL.entity(...)`to make it typed again and add one more segment to it. Note, that this does not check that original reference is indeed the reference to the book, this only lets you use required model interface.
The result of both is the same reference. Model interfaces are strongly recommended for custom handlers as they are easier to use.
1409
+
With `CQL.to(...)`the same is produced dynamically.
1359
1410
1360
-
If you need to navigate to the parent, you can do it using the dynamic syntax to strip the last segment of it. This also accounts for the case when the reference contains longer path.
You can also construct ref that starts from the first segment to navigate to different path of the same root.
1426
+
There is the method `rootSegment()` that can be used to construct the reference starting with the same root as the existing reference. This is useful when you require navigation to different part of the same structured type, e.g. for example from the book's author to the pages of it.
StructuredTypeRef copy = builder.build(); // new reference is ready
1391
1452
```
1392
1453
1393
-
Filters that you define for references can contain complex predicates referring to other elements, for example, to express complex conditions and path expressions.
1394
-
1395
-
Segments of the references also usable as the variables and you can inspect them.
1396
-
1397
-
```java
1398
-
r.rootSegment().id(); // yields Books
1399
-
r.rootSegment().filter(); // filter an Optional with the predicate
1400
-
```
1454
+
The code that manipulates the references must be tested thoroughly and you always need to ensure that you do not loose the filters or change the reference so that it becomes inconsistent.
1401
1455
1402
-
If you want to reflect the types behind the ref, you need to use [`CqnAnalyzer`](/java/working-with-cql/query-introspection#cqnanalyzer) that parses it and binds it back to the model. Use it, for example, to find annotations or extract key values.
1403
-
1404
-
References are not comparable so they cannot be used as a keys in maps and values in the sets. You should not compare references between each other.
1405
-
1406
-
Each reference can be serialized as JSON and also renders JSON as its `toString()` implementation. Do not use this JSON to process the references, for example, to extract values from them or to compare references between each other.
1456
+
:::warning Limitation
1457
+
The references are not comparable between each other. They cannot be used as keys of maps or values in a set.
0 commit comments