cancel
Showing results for 
Search instead for 
Did you mean: 

[CDS - SAP CAP for Java] Structure of Generated Java classes

rajendra3041-32
Discoverer
0 Kudos
1,257

Hi,

I'm seeing a certain behaviour in the generated java classes for the CDS entities/service as modelled below - which I'm having a slightly tough time following. I've tried to explain it with a simple example below.

Start with the below entity and service models.

db/Orders.cds

namespace ns;


entity Orders : cuid {
  customer : String;
  items    : Composition of many OrderItems on items.id = $self.id;
}

entity OrderItems : cuid {
  order    : Association to one Orders on order.id = $self.id;
  product  : String;
}

srv/OrdersService.cds

using {ns} from '../db/Orders';

service OrdersService {
  entity Orders as projection on ns.Orders;
}

Run cds build --for java-cf in terminal.

Among the generated files in the Orders_ java class has a method items() with return type as OrderItems_

srv/src/gen/java/cds/gen/ordersservice/Orders_.java:

package cds.gen.ordersservice;
...
@CdsName("OrdersService.Orders")
public interface Orders_ extends StructuredType<Orders_> {
String CDS_NAME = "OrdersService.Orders";
...
OrderItems_ items();
OrderItems_ items(Function<OrderItems_, CqnPredicate> filter);
}

Add a new entity in OrderService.cds

srv/OrdersService.cds

using {ns} from '../db/Orders';

service OrdersService {
  entity Orders as projection on ns.Orders;

  @cds.persistence.skip
  entity ServiceItems : ns.OrderItems {
    faultCode  : String;
  }
}

The new ServiceItems entity extends OrderItems entity [has all the fields of OrderItems entity and one additional computed field]. It isn't persisted (hence @cds.persistence.skip).

The reason for adding it is - it will be eventually used as return type of an unbound function in the OrdersService. The faultCode will be computed in the event handler for the unbound function.

At this stage, when I ran cds build --for java-cf again in terminal, the generated Java class for Orders_ looks like below.

package cds.gen.ordersservice;
...
@CdsName("OrdersService.Orders")
public interface Orders_ extends StructuredType<Orders_> {
String CDS_NAME = "OrdersService.Orders";
...
ServiceItems_ items();
ServiceItems_ items(Function<ServiceItems_, CqnPredicate> filter);
}

As can be seen above, the return type of items() in Orders_ has changed to ServiceItems_ (from OrderItems_).

Even though nothing was changed nothing with regard to the Orders entity changed, why does the generated Java class for Orders_ change?

This later becomes a problem while composing the CqnSelect in the event handler for an unbound function of the service (while trying to populate the value of computed field faultCode).

View Entire Topic
adrian_goerler
Advisor
Advisor
0 Kudos

The issue is not related to the generated Java code only.

As you define the ServiceItems entity in the OrdersService the OrdersService.Orders.items association is redirected to the OrdersService.ServiceItems entity.

See: https://cap.cloud.sap/docs/cds/cdl#auto-redirect

> The new ServiceItems entity extends OrderItems entity [has all the fields of OrderItems entity and one additional computed field]. It isn't persisted (hence @cds.persistence.skip).

> The reason for adding it is - it will be eventually used as return type of an unbound function in the OrdersService. The faultCode will be computed in the event handler for the unbound function.

Please consider to rather define ServiceItems as a type instead to avoid the redirect.

rajendra3041-32
Discoverer
0 Kudos

Thanks Adrian. I didn’t realize that auto-redirect would happen here.


Since I annotated the ServiceItems entity as @cds.persistence.skip, I started seeing runtime errors.

Thanks again