Advanced Concepts

    Find here an overview of advanced concepts.


    The CDS Data Store

    The Data Store API is used to execute CQN statements against the underlying data store (typically a database). It’s a technical component that allows to execute CDS QL statements. The CDS Data Store is used to implement the Persistence Service, but is also available independent from the CAP Java SDK. So, it’s not a service and isn’t based on events and event handlers.

    The CdsDataStore API is similar to the CqnService API. The only difference is, that the run method is called execute:

    CdsDataStore dataStore = ...;
    Select query = Select.from("bookshop.Books").where(b -> b.get("ID").eq(17));
    Result result = dataStore.execute(query);

    Use the CdsDataStore API to set user session context information. Utilize the SessionContext API which follows a builder pattern, as shown in the following example:

    SessionContext sessionContext = SessionContext.create().setUserContext(UserContext.create().setLocale(Locale.US).build()).build());

    When implementing a CAP application, using the Persistence Service is preferred over the CDS Data Store.

    Using CDS QL with a Static CDS Model

    The static model and accessor interfaces can be generated using the CDS Maven Plugin.

    ❗ Warning
    Currently, the generator doesn’t support using reserved Java keywords as identifiers in the CDS model. Conflicting element names can be renamed in Java using the annotation.

    Static Model in the Query Builder

    The Query Builder API allows you to dynamically create CDS QL queries using entity and element names given as strings:

      .where(book ->"author").get("name").eq("Edgar Allan Poe"));

    This query is constructed dynamically. It’s checked only at runtime that the entity my.bookshop.Authors actually exists and that it has the element name. Moreover, the developer of the query doesn’t get any code completion at design time. These disadvantages are avoided by using a static model to construct the query.

    Model Interfaces

    The static model is a set of interfaces that reflects the structure of the CDS model in Java (like element references with their types, associations, etc.) and allow to fluently build queries in a type-safe way. For every entity in the model, the model contains a corresponding StructuredType interface, which represents this type. As an example, for this CDS model the following model interfaces are generated:

    CDS model

    namespace my.bookshop;
    entity Books {
      key ID : Integer;
      title  : String(111);
      author : Association to Authors;
    entity Authors {
      key ID : Integer;
      name   : String(111);
      books  : Association to many Books on = $self;

    Find this source also in cap/samples.


    public interface Books_ extends StructuredType<Books_> {
      ElementRef<Integer> ID();
      ElementRef<String> title();
      Authors_ author();
      Authors_ author(Function<Authors_, Predicate> filter);
    public interface Authors_ extends StructuredType<Authors_> {
      ElementRef<Integer> ID();
      ElementRef<String> name();
      Books_ books();
      Books_ books(Function<Books_, Predicate> filter);

    Accessor Interfaces

    The corresponding data is captured in a data model similar to JavaBeans. These beans are interfaces generated by the framework and providing the data access methods - getters and setters - and containing the CDS element names as well. The instances of the data model are created by the CDS QL Execution Engine (see the following example).

    Note the following naming convention: the model interfaces, which represent the structure of the CDS Model, always end with underscore, for example Books_. The accessor interface, which refers to data model, is simply the name of the CDS entity - Books.

    The following data model interface is generated for Books:

    public interface Books extends CdsData {
      String ID = "ID";
      String TITLE = "title";
      String AUTHOR = "author";
      Integer getID();
      void setID(Integer id);
      String getTitle();
      void setTitle(String title);
      Authors getAuthor();
      void setAuthor(Map<String, ?> author);


    In the query builder, the interfaces reference entities. The interface methods can be used in lambda expressions to reference elements or to compose path expressions:

    Select<Books_> query = Select.from(Books_.class)			// Note the usage of model interface Books_ here
      .columns(book -> book.title())
      .where  (book ->"Edgar Allan Poe"));
    List<Books> books = dataStore.execute(query).listOf(Books.class);	// After executing the query the result can be converted to a typed representation List of Books.
    Show/Hide Beta Features