Skip to content
Search

    April 2022

    Welcome to the notes for the April 2022 release for the CAP framework. Find the most noteworthy news and changes in the following sections.

    Find bugfixes and enhancements in the Changelog.

    The April 2022 release only contains updates for the CAP Service SDK for Java.


    Java SDK

    Important Changes ❗️

    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 (goal watch).
    • 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 using an accessor interface facade, you can use a path as key to write to 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:
    • Pessimistic locking via Select.lock with a timeout of 0 (NOWAIT) is now also supported on PostgreSQL.