---
title: April 2025
versions:
  cdsjs: 8.9.0+
  cdsdk: 8.9.0+
  cdsc: 5.9.0+
  cdsmtxs: 2.7.0+
  java: 3.10.0+
---

# April 2025

<ReleaseBadges />


[[toc]]

## Prepare for Major Release

Along with new features, the next major release CDS 9 will contain some changes that you'll need to react on.
You can do this already **now**, which eases the transition. You can't use the mentioned **deprecated functions** with the CDS 9 release. The corresponding compatibility flags won't be respected any longer.

See [CDS Language & Compiler](#cds) and [Node.js](#cds-js).

<span id="internalnote" />

## CDS Language & Compiler {#cds}

In preparation for the upcoming major release, [**switch on** the new CDS parser.](feb25#new-parser)

## Node.js {#cds-js}

Use this month to get prepared for the upcoming major release. Here's are the things you can and should already enable and test:

- [**Upgrade to** `@sap/xssec 4`.](jan25#upgrade-to-sapxssec-4) _--> remove compat flag_
- [**Adapt to changed behavior** when processing `@restrict.where` checks.](../2024/dec24#consolidated-authorization-checks)
- [**Adopt** @cap-js database services now.](../2024/jun24#new-database-services-ga)
- [**Switch on** the new protocol adapters.](../2024/jun24#new-protocol-adapters-ga) _--> remove compat flag_
- [**Switch on** lean draft.](../2024/jun24#lean-draft) _--> remove compat flag_
- [**Migrate** ESLint Configuration](feb25#migrate-eslint-configuration)
- [**Add** Test Support Package](feb25#add-test-support-package)


## Java {#cds-java}

### Optimized Outbox
Technical [Outbox Service](/@external/java/event-queues#default-outbox-services) offers CAP applications a generic API to emit events to (Remote) CDS Services in a resilient way.
By default, CAP auditlog and messaging events are sent via the Outbox.
The internal Outbox processing is now optimized to serve high-scale load profiles across many tenants using task queues internally.
As a consequence, the persistence of a tenant's outbox only needs to be queried when needed, and resource consumption is significantly reduced due to the massively reduced DB connection usage.

To benefit from the task-based Outbox processing, you need to explicitly set <Config java>cds.taskScheduler.enabled: true</Config>.
In future versions of CAP Java, the optimized Outbox will be enabled by default.

<span id="java-flows" />

<span id="java-assert-constraints" />

<span id="java-dynamic-validation" />

<span id="java-cf-profiler" />

### Remote OData Singletons

CAP Java now supports consuming _singleton_ instances from remote OData services during remote service consumption. This is particularly useful for scenarios where a single, globally shared entity needs to be accessed. For example, `OverallStatus` could represent the health status of an entire system:

```xml
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
  <edmx:DataServices>
      <EntityContainer Name="EntityContainer">
        <Singleton Name="OverallStatus" Type="health.OverallStatus"/> <!-- [!code highlight] -->
      </EntityContainer>
      <EntityType Name="OverallStatus">
        <Key>
          <PropertyRef Name="id"/>
        </Key>
        <Property Name="id" Type="Edm.Int32" Nullable="false"/>
        <Property Name="status" Type="Edm.String"/>
      </EntityType>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>
```

This EDMX model defines the singleton `OverallStatus`. It can now be accessed using remote service consumption as usual:

```java
CqnSelect selectStatus = Select.from(OVERALL_STATUS);
OverallStatus status = remoteService.run(selectStatus).single(OverallStatus.class);
```

### Enhanced Search

The `@Common.Text` annotation allows you to specify a property that holds a text to be displayed on the UI instead of the value of the annotated property. To enhance the user experience, the property that holds the display text is now searched by default:

```cds
entity Books : cuid {
title  : String;
@Common.Text : author.name
author : Association to Authors;
}
entity Authors : cuid {
name : String;
}
```

Here the value of the `name` property of the `Authors` entity is displayed instead of the `author` association and is now also searched automatically, without requiring additional configuration.


### To-many Expand on Subqueries

You can now expand to-many associations from [subqueries](/@external/java/working-with-cql/query-api#from-select) if the association is selected implicitly via select all in the inner query:

```java
CqnSelect authorsUnder40 = Select.from(AUTHORS)
   .excluding(a -> a.placeOfBirth())
   .where(a -> a.age().lt(40));
Select.from(authorsUnder40).columns(
    a -> a.get("name"),
    a -> a.to("books").expand("title"));
```

### New Functions in CDS QL

The following new functions are now supported by CDS QL in CAP Java:

#### Arithmetic Functions

* round
* floor
* ceiling

#### String Functions

* length
* indexof (zero-based)
* trim

The functions are available on the `Value` interface as well as on the `CQL` helper class. Examples:

```java
CqnSelect booksWithShortTitle = Select.from(BOOKS).where(b -> title().length().lt(10));
CqnSelect averagePriceRoundedByGenre = Select.from(BOOKS)
    .columns(b -> b.genre().name(), b.price().avg().round())
    .groupBy(b -> b.genre().name());
```

The functions are implemented in a database-agnostic way with semantics aligned with OData v4:
* [Arithmetic Functions](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#_Toc31361011)
* [String Functions](https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#_Toc31360991)

### Miscellaneous
* The `Result.rowType()` method, which returns the structured type of each row of a query result, is now also supported for insert, upsert, and update results.
* Expands from and to entities with aliased keys are now also supported.


## CAP Plugins

<span id="ams-local" />

### Attachments: Multitenancy

[@cap-js/attachments](https://github.com/cap-js/attachments) now supports multitenancy with both shared and tenant-specific object store instances. By default, the plugin uses a separate object store instance for each tenant to ensure complete data isolation.

The tenant-specific object store instance scenario is sketched in the following figure:

![Attachments - Multitenancy Separate Mode](assets/april25/attachments-mtx.drawio.svg){width=600px}

### Change Tracking: Multitenancy

[@cap-js/change-tracking](https://github.com/cap-js/change-tracking) now supports multitenancy and extensibility using MTX-S sidecar deployments.


<span id="guide-shared" />
