April 2022
Welcome to the release of CAP. Find the most noteworthy news and changes in the following sections.The April 2022 release only contains updates for the CAP Service SDK for Java.
Java SDK
Important Changes ❗️
- Path access via the get method is deprecated. See Convenience for Struct Data.
- The CDS model is no longer reloaded every time when opening a new Request Context. See Optimized Model Propagation.
Spring Boot Developer Tools
CAP Java SDK now provides full support for Spring Boot Developer Tools. The tools contain a bunch of handy development-time features that help you to reduce roundtrip times in local but also remote development scenarios:
- Automatic application update on CDS model, configuration, or code changes.
- Benefit from
cds-maven-plugin
integration (goalwatch
). - Benefit from IDE integrations (Eclipse, IntelliJ IDEA, VS Code).
- LiveReload support to trigger an instantaneous browser refresh.
- Remote Update: deploy once and upload changes done locally at runtime.
To activate the developer tools, add the following in your development profile:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
Optimized Model Propagation
The CDS model is no longer reloaded every time when opening a new Request Context. Only the outmost Request Context initially loads the CDS model and propagates it to all inner Request Contexts.
The only scenario where the model is still reloaded is when the new Request Context uses a different tenant. This scenario also requires a new ChangeSet Context to be opened in addition. If a ChangeSet Context is opened without an existing Request Context the latter is opened implicitly as well.
Optimized $metadata
Requests
The $metadata
endpoints now stream the original EDMX directly, without serializing the internal Olingo EDMX representation. This results in a much better performance. It also allows you to use OData dynamic expressions.
Enhanced $user.<attr>
Usages
Now, user attribute values $user.<attr>
can be automatically assigned to elements annotated with @cds.on.insert
or @cds.on.update
:
entity UserData {
@cds.on.insert : '$user.organization'
organization : String;
@cds.on.insert : '$user.departments'
departments: array of String;
}
As user attributes in general have a list of values, you can also fill an element of arrayed String
type.
Improved Deep Updates
Deep Update now supports changing to-one associations to different target entities.
- associations can be set to either new (nonexisting) or existing target entities
- compositions can only be set to new target entities that are created by the deep update
If a deep update contains data for a to-one association, the data for this association is ignored instead of throwing an exception, when the following applies:
- Doesn't cascade the update operation (default).
- Data doesn't set the association to another target entity.
Deep Updates over associations cascading both the insert and update operation now support creating new target entities with data containing an InputStream
for a LargeString
or LargeBinary
element. In this case, an additional query is executed to determine if the target entity already exists.
Inserting target entities with key elements of type String
and @cds.on.insert: $uuid
annotation are now also supported.
Convenience for Struct Data
If you access a Map
via an accessor interface facade, you can use the *Path
methods to manipulate nested maps:
CdsData data = Struct.create(CdsData.class);
data.putPath("deeply.nested.key", "value");
This results in a deeply nested data structure: { "deeply" : { "nested" : { "key" : "value" } } }
.
Read access to deeply nested data is supported via getPath. Path access via the get method is deprecated.
String v = data.getPath("deeply.nested.key");
To check if the data contains a nested map with a specific key use containsPath
:
boolean b = data.containsPath("deeply.nested.key");
To do a deep remove use removePath
:
String oldValue = data.removePath("deeply.nested.key");
Miscellaneous
Spring's
@Order
annotation on event handler classes is now respected and event handlers are registered in that order.Enhanced UserInfo in case of IAS authentication:
- UserInfo.getName() represents the token subject (
sub
) identifying the request user ($user
). - UserInfo.getAdditionalAttributes() contains all token claims such as
email
oraud
.
- UserInfo.getName() represents the token subject (
The persistent outbox can now store the last error message for an outbox entry if it failed to process it.
Pessimistic locking via
Select.lock
with a timeout of 0 (NOWAIT) is now also supported on PostgreSQL.