Skip to content

Commit ed5b25a

Browse files
Release 2025-07-04 (#1954)
2 parents d39b5c0 + 1b11906 commit ed5b25a

File tree

26 files changed

+3957
-1431
lines changed

26 files changed

+3957
-1431
lines changed

.vitepress/config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ config.rewrites = rewrites
106106
// Add custom capire info to the theme config
107107
config.themeConfig.capire = {
108108
versions: {
109-
java_services: '4.0.2',
110-
java_cds4j: '4.0.2'
109+
java_services: '4.1.1',
110+
java_cds4j: '4.1.1'
111111
},
112112
gotoLinks: []
113113
}

advanced/odata.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,9 +1111,12 @@ Provide support for hierarchy attribute calculation and navigation, and allow th
11111111

11121112
- <sup>(1)</sup> Beta feature, API may change
11131113

1114-
::: warning
1115-
Generic implementation is supported on SAP HANA only
1116-
:::
1114+
Generic implementation is supported on the following databases:
1115+
1116+
| | SAP HANA | H2 | PostgreSQL | SQLite |
1117+
|---|---|---|---|---|
1118+
| CAP Java ||| | |
1119+
| CAP Node.js || |||
11171120

11181121
:::info
11191122
The source elements of the entity defining the recursive parent-child relation are identified by a naming convention or aliases `node_id` and `parent_id`.

guides/databases-hana.md

Lines changed: 82 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
---
22
status: released
3-
impl-variants: true
43
---
54

65
# Using SAP HANA Cloud for Production
76

8-
<ImplVariantsHint />
9-
107
[[toc]]
118

129

@@ -20,52 +17,42 @@ CAP isn't validated with other variants of SAP HANA, like "SAP HANA Database as
2017

2118
## Setup & Configuration
2219

23-
<div class="impl node">
24-
25-
Run this to use SAP HANA Cloud for production:
20+
To use SAP HANA Cloud for production, add a dependency to the _package.json_ for Node.js or to the _pom.xml_ for a CAP Java application:
2621

27-
```sh
22+
::: code-group
23+
```sh [Shell/Bash]
2824
npm add @cap-js/hana
2925
```
3026

31-
::: details Using other SAP HANA drivers...
32-
33-
Package `@cap-js/hana` uses the [`hdb`](https://www.npmjs.com/package/hdb) driver by default. You can override that by running [`npm add @sap/hana-client`](https://www.npmjs.com/package/@sap/hana-client), thereby adding it to your package dependencies, which then takes precedence over the default driver.
34-
35-
:::
36-
37-
::: tip Prefer `cds add`
38-
39-
... as documented in the [deployment guide](deployment/to-cf#_1-sap-hana-database), which also does the equivalent of `npm add @cap-js/hana` but in addition cares for updating `mta.yaml` and other deployment resources.
40-
41-
:::
42-
43-
</div>
44-
45-
<div class="impl java">
46-
47-
To use SAP HANA Cloud, [configure a module](../java/developing-applications/building#standard-modules), which includes the feature `cds-feature-hana`.
48-
For example, add a Maven runtime dependency to the `cds-feature-hana` feature:
49-
50-
```xml
27+
```xml [pom.xml]
5128
<dependency>
5229
<groupId>com.sap.cds</groupId>
5330
<artifactId>cds-feature-hana</artifactId>
5431
<scope>runtime</scope>
5532
</dependency>
5633
```
34+
:::
5735

58-
::: tip
36+
::: details Using other SAP HANA drivers...
5937

60-
The [modules](../java/developing-applications/building#standard-modules) `cds-starter-cloudfoundry` and `cds-starter-k8s` include `cds-feature-hana`.
38+
Package `@cap-js/hana` uses the [`hdb`](https://www.npmjs.com/package/hdb) driver by default. You can override that by running [`npm add @sap/hana-client`](https://www.npmjs.com/package/@sap/hana-client), thereby adding it to your package dependencies, which then takes precedence over the default driver.
6139

6240
:::
6341

64-
The datasource for HANA is then auto-configured based on available service bindings of type *service-manager* and *hana*.
42+
:::details In CAP Java ...
43+
The [modules](../java/developing-applications/building#standard-modules) `cds-starter-cloudfoundry` and `cds-starter-k8s` include `cds-feature-hana`.
44+
45+
The datasource for SAP HANA is then auto-configured based on available service bindings of type *service-manager* and *hana*.
6546

6647
[Learn more about the configuration of an SAP HANA Cloud Database](../java/cqn-services/persistence-services#sap-hana){ .learn-more}
48+
:::
49+
50+
::: tip Prefer `cds add`
51+
52+
... as documented in the [deployment guide](deployment/to-cf#_1-sap-hana-database), which also does the equivalent of `npm add @cap-js/hana` but in addition cares for updating `mta.yaml` and other deployment resources.
53+
54+
:::
6755

68-
</div>
6956

7057

7158

@@ -266,41 +253,86 @@ The HANA Service provides dedicated support for native SAP HANA features as foll
266253

267254
### Vector Embeddings { #vector-embeddings }
268255

269-
Vector embeddings are numerical representations that capture important features and semantics of unstructured data - such as text, images, or audio. This representation makes vector embeddings of similar data have high similarity and low distance to each other. These properties of vector embeddings facilitate tasks like similarity search, anomaly detection, recommendations and Retrieval Augmented Generation (RAG). Vector embeddings from a vector datastore such as the [SAP HANA Cloud Vector Engine](https://community.sap.com/t5/technology-blogs-by-sap/sap-hana-cloud-s-vector-engine-announcement/ba-p/13577010) can help get better generative AI (GenAI) results. This is achieved when the embeddings are used as context to the large language models (LLMs) prompts.
256+
Vector embeddings let you add semantic search, recommendations, and generative AI features to your CAP application. Embeddings are numeric arrays that represent the meaning of unstructured data (text, images, etc.), making it possible to compare and search for items that are semantically related to each other or a user query.
270257

271-
Typically vector embeddings are computed using an **embedding model**. The embedding model is specifically designed to capture important features and semantics of a specific type of data, it also determines the dimensionality of the vector embedding space. Unified consumption of embedding models and LLMs across different vendors and open source models is provided via the [SAP Generative AI Hub](https://community.sap.com/t5/technology-blogs-by-sap/how-sap-s-generative-ai-hub-facilitates-embedded-trustworthy-and-reliable/ba-p/13596153).
258+
#### Choose an Embedding Model
272259

273-
In CAP, vector embeddings are stored in elements of type [cds.Vector](../cds/types):
260+
Choose an embedding model that fits your use case and data (for example english or multilingual text). The model determines the number of dimensions of the resulting output vector. Check the documentation of the respective embedding model for details.
274261

275-
```cds
276-
entity Books : cuid { // [!code focus]
277-
title : String(111);
278-
description : LargeString; // [!code focus]
279-
embedding : Vector(1536); // vector space w/ 1536 dimensions // [!code focus]
280-
} // [!code focus]
262+
Use the [SAP Generative AI Hub](https://community.sap.com/t5/technology-blogs-by-sap/how-sap-s-generative-ai-hub-facilitates-embedded-trustworthy-and-reliable/ba-p/13596153) for unified consumption of embedding models and LLMs across different vendors and open source models. Check for available models on the [SAP AI Launchpad](https://help.sap.com/docs/ai-launchpad/sap-ai-launchpad-user-guide/models-and-scenarios-in-generative-ai-hub-fef463b24bff4f44a33e98bb1e4f3148#models).
263+
264+
#### Add Embeddings to Your CDS Model
265+
Use the `cds.Vector` type in your CDS model to store embeddings on SAP HANA Cloud. Set the dimension to match your embedding model (for example, 1536 embedding dimensions for OpenAI *text-embedding-3-small*).
266+
267+
```cds
268+
entity Books : cuid {
269+
title : String(111);
270+
description : LargeString;
271+
embedding : Vector(1536); // adjust dimensions to embedding model
272+
}
273+
```
274+
275+
#### Generate Embeddings
276+
Use an embedding model to convert your data (for example, book descriptions) into vectors. The [SAP Cloud SDK for AI](https://sap.github.io/ai-sdk/) makes it easy to call SAP AI Core services to generate these embeddings.
277+
278+
:::details Example using SAP Cloud SDK for AI
279+
```Java
280+
var aiClient = OpenAiClient.forModel(OpenAiModel.TEXT_EMBEDDING_3_SMALL);
281+
var response = aiClient.embedding(
282+
new OpenAiEmbeddingRequest(List.of(book.getDescription())));
283+
book.setEmbedding(CdsVector.of(response.getEmbeddingVectors().get(0)));
281284
```
285+
:::
282286

283-
At runtime, you can compute the similarity and distance of vectors in the SAP HANA vector store using the `cosineSimilarity` and `l2Distance` (Euclidean distance) functions in queries:
287+
#### Query for Similarity
288+
At runtime, use SAP HANA's built-in vector functions to search for similar items. For example, find books with embeddings similar to a user question:
284289

285290
::: code-group
286-
```js [Node.js]
287-
let embedding; // vector embedding as string '[0.3,0.7,0.1,...]';
291+
```Java [Java]
292+
// Compute embedding for user question
293+
var request = new OpenAiEmbeddingRequest(List.of("How to use vector embeddings in CAP?"));
294+
CdsVector userQuestion = CdsVector.of(
295+
aiClient.embedding(request).getEmbeddingVectors().get(0));
296+
// Compute similarity between user question and book embeddings
297+
var similarity = CQL.cosineSimilarity( // computed on SAP HANA
298+
CQL.get(Books.EMBEDDING), userQuestion);
299+
// Find Books related to user question ordered by similarity
300+
hana.run(Select.from(BOOKS).limit(10)
301+
.columns(b -> b.ID(), b -> b.title(),
302+
b -> similarity.as("similarity"))
303+
.orderBy(b -> b.get("similarity").desc()));
304+
```
288305

306+
```js [Node.js]
307+
const response = await new AzureOpenAiEmbeddingClient(
308+
'text-embedding-3-small'
309+
).run({
310+
input: 'How to use vector embeddings in CAP?'
311+
});
312+
const questionEmbedding = response.getEmbedding();
289313
let similarBooks = await SELECT.from('Books')
290-
.where`cosine_similarity(embedding, to_real_vector(${embedding})) > 0.9`
314+
.where`cosine_similarity(embedding, to_real_vector(${questionEmbedding})) > 0.9`;
291315
```
292316

293-
```java [Java]
294-
// Vector embedding of text, for example, from SAP GenAI Hub or via LangChain4j
295-
float[] embedding = embeddingModel.embed(bookDescription).content().vector();
317+
:::
296318

297-
Result similarBooks = service.run(Select.from(BOOKS).where(b ->
298-
CQL.cosineSimilarity(b.embedding(), CQL.vector(embedding)).gt(0.9)));
299-
```
319+
:::tip
320+
Store embeddings when you create or update your data. Regenerate embeddings if you change your embedding model.
300321
:::
301322

323+
:::tip SAP Cloud SDK for AI
324+
Use the [SAP Cloud SDK for AI](https://sap.github.io/ai-sdk/) for unified access to embedding models and large language models (LLMs) from [SAP AI Core](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/what-is-sap-ai-core).
325+
:::
326+
327+
328+
[Learn more about the SAP Cloud SDK for AI (Java)](https://sap.github.io/ai-sdk/docs/java/getting-started) {.learn-more}
329+
302330
[Learn more about Vector Embeddings in CAP Java](../java/cds-data#vector-embeddings) {.learn-more}
303331

332+
[Learn more about the SAP Cloud SDK for AI (JavaScript)](https://sap.github.io/ai-sdk/docs/js/getting-started) {.learn-more}
333+
334+
335+
304336

305337
### Geospatial Functions
306338

guides/deployment/microservices.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,10 @@ cd shared-db
159159
```
160160

161161
```sh
162-
cds db -2 sql
162+
cds compile db -2 sql
163163
```
164164
```sh
165-
cds db -2 hana
165+
cds compile db -2 hana
166166
```
167167

168168
```sh

guides/deployment/to-cf.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ npm i @sap/cds #> if necessary
120120

121121
```sh
122122
cf add-plugin-repo CF-Community https://plugins.cloudfoundry.org
123-
cf install-plugin multiapps
124-
cf install-plugin html5-plugin
123+
cf install-plugin -f multiapps
124+
cf install-plugin -f html5-plugin
125125
```
126126

127127
## Prepare for Production {#prepare-for-production}

guides/extensibility/feature-toggles.md

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ This feature extends corresponding SAP Fiori annotations to display already exis
127127
Note the following limitations for `.cds` files in features:
128128

129129
- no `.cds` files in subfolders, for example, `fts/isbn/sub/file.cds`
130-
- no `using` dependencies between features
130+
- no `using` dependencies between features, any entity, service or type that you refer to or extend needs to be part of the base model
131131
- further limitations re `extend aspect` → to be documented
132132
:::
133133

@@ -255,18 +255,12 @@ An MTX sidecar is a standard, yet minimalistic Node.js CAP project. By default i
255255
{
256256
"name": "mtx-sidecar", "version": "0.0.0",
257257
"dependencies": {
258-
"@sap/cds": "^7",
259-
"@sap/cds-mtxs": "^1",
258+
"@sap/cds": "^9",
259+
"@sap/cds-mtxs": "^3",
260260
"express": "^4"
261261
},
262262
"cds": {
263-
"requires": {
264-
"cds.xt.ModelProviderService": "in-sidecar"
265-
},
266-
"[development]": {
267-
"requires": { "auth": "dummy" },
268-
"server": { "port": 4005 }
269-
}
263+
"profile": "mtx-sidecar"
270264
}
271265
}
272266
```

guides/messaging/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ Find the code to emit events in *[@capire/reviews/srv/reviews-service.js](https:
157157
class ReviewsService extends cds.ApplicationService { async init() {
158158

159159
// Emit a `reviewed` event whenever a subject's avg rating changes
160-
this.after (['CREATE','UPDATE','DELETE'], 'Reviews', (req) => {
160+
this.after (['CREATE','UPDATE','DELETE'], 'Reviews', (_, req) => {
161161
let { subject } = req.data, count, rating //= ...
162162
return this.emit ('reviewed', { subject, count, rating })
163163
})

guides/multitenancy/mtxs.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,14 +174,14 @@ An MTX sidecar is a standard, yet minimal Node.js CAP project. By default it's a
174174
{
175175
"name": "bookshop-mtx", "version": "0.0.0",
176176
"dependencies": {
177-
"@sap/cds": "^7",
178-
"@sap/cds-hana": "^2",
179-
"@sap/cds-mtxs": "^1",
177+
"@sap/cds": "^9",
178+
"@cap-js/hana": "^2",
179+
"@sap/cds-mtxs": "^3",
180180
"@sap/xssec": "^4",
181181
"express": "^4"
182182
},
183183
"devDependencies": {
184-
"@cap-js/sqlite": "^1"
184+
"@cap-js/sqlite": "^2"
185185
},
186186
"scripts": {
187187
"start": "cds-serve"

guides/providing-services.md

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,9 +1109,9 @@ module.exports = class Sue extends cds.Service {
11091109
```js
11101110
GET .../sue/sum(x=1,y=2) // unbound function
11111111
GET .../sue/stock(id=2) // unbound function
1112-
POST .../sue/add {"x":1,"to":2} // unbound action
1112+
POST .../sue/add {"x":11,"to":2} // unbound action
11131113
GET .../sue/Foo(2)/Sue.getStock() // bound function
1114-
POST .../sue/Foo(2)/Sue.order {"x":1} // bound action
1114+
POST .../sue/Foo(2)/Sue.order {"x":3} // bound action
11151115
```
11161116

11171117
> Note: You always need to add the `()` for functions, even if no arguments are required. The OData standard specifies that bound actions/functions need to be prefixed with the service's name. In the previous example, entity `Foo` has a bound action `order`. That action must be called via `/Foo(2)/Sue.order` instead of simply `/Foo(2)/order`.
@@ -1123,18 +1123,45 @@ POST .../sue/Foo(2)/Sue.order {"x":1} // bound action
11231123
<br>
11241124

11251125

1126-
**Programmatic** usage via **generic APIs** would look like this for Node.js:
1126+
**Programmatic** usage via **generic APIs** for Node.js:
1127+
1128+
For unbound actions and functions:
1129+
1130+
```ts
1131+
async function srv.send (
1132+
event : string | { event, data?, headers?: object },
1133+
data? : object | any
1134+
)
1135+
return : result of this.dispatch(req)
1136+
```
1137+
1138+
For bound actions and functions:
1139+
1140+
```ts
1141+
async function srv.send (
1142+
event : string | { event, entity, data?, params?: array of object, headers?: object },
1143+
entity : string,
1144+
data? : object | any
1145+
)
1146+
return : result of this.dispatch(req)
1147+
```
1148+
1149+
- `event` is a name of a custom action or function
1150+
- `entity` is a name of an entity
1151+
- `params` are keys of the entity instance
1152+
1153+
Programmatic usage would look like this for Node.js:
11271154

11281155
```js
11291156
const srv = await cds.connect.to('Sue')
11301157
// unbound actions/functions
11311158
await srv.send('sum',{x:1,y:2})
1132-
await srv.send('add',{x:11,to:2})
11331159
await srv.send('stock',{id:2})
1134-
// bound actions/functions
1160+
await srv.send('add',{x:11,to:2})
1161+
// actions/functions bound to collection
11351162
await srv.send('getStock','Foo',{id:2})
1136-
//for passing the params property, use this syntax
1137-
await srv.send({ event: 'order', entity: 'Foo', data: {x:3}, params: [2]})
1163+
// for actions/functions bound to entity instance, use this syntax
1164+
await srv.send({ event: 'order', entity: 'Foo', data: {x:3}, params: [{id:2}]})
11381165
```
11391166

11401167
> Note: Always pass the target entity name as second argument for bound actions/functions.
@@ -1147,8 +1174,8 @@ POST .../sue/Foo(2)/Sue.order {"x":1} // bound action
11471174
const srv = await cds.connect.to(Sue)
11481175
// unbound actions/functions
11491176
srv.sum(1,2)
1150-
srv.add(11,2)
11511177
srv.stock(2)
1178+
srv.add(11,2)
11521179
// bound actions/functions
11531180
srv.getStock('Foo',2)
11541181
srv.order('Foo',2,3)

guides/security/authorization.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ service SomeService {
190190

191191
#### Events to Auto-Exposed Entities { #events-and-auto-expose}
192192

193-
In general, entities can be exposed in services in different ways: it can be **explicitly exposed** by the modeler (for example, by a projection), or it can be **auto-exposed** by the CDS compiler due to some reason.
193+
In general, entities can be exposed in services in different ways: they can be **explicitly exposed** by the modeler (for example, by a projection), or they can be **auto-exposed** by the CDS compiler due to some reason.
194194
Access to auto-exposed entities needs to be controlled in a specific way. Consider the following example:
195195

196196
```cds

0 commit comments

Comments
 (0)