diff --git a/java/change-tracking.md b/java/change-tracking.md index a55918d0a..676ae3597 100644 --- a/java/change-tracking.md +++ b/java/change-tracking.md @@ -283,15 +283,70 @@ values of the entity: data that weren't present in the old values are considered the new values are considered as deleted. Elements that are present in both old and new values but have different values are considered as modified. Each change detected by the change tracking feature is stored in the change log as a separate entry. +As a rule, specify primary keys to modify change tracked entities and avoid using [searched updates](/java/working-with-cql/query-api#searched-update). + +### Changes in Deeply Structured Documents + In the case of the deeply structured documents, for example, entities with the compositions, the change tracking feature detects the changes across the complete document and stores them in the change log with the metadata reflecting the structure of the change. -Take the order and item model used previously in this guide as an example. If you change values for the tracked elements with the deep update, for example, the customer name in the order and the quantity of the item, the change log contains two entries: one for the order and one for the item. The change log entry for the item will also reflect that the root of the change is an order. Both changes will be reachable through the association `changes` of the order entity. +Take the order and item model used previously in this guide as an example. + +For deep updates, use the [delta representation](/java/working-with-cql/query-api#deep-update-delta) for its items or the [full set representation](/java/working-with-cql/query-api#deep-update-full-set) to overwrite complete document. + +The following example yields two changelog entries: one for the order and one for the item. The change log entry for the item reflects that the root of the change is an order. Both changes are reachable through the association `changes` of the order entity. + +```java +Orders order = Orders.create("..."); +order.setOrderNo("N1"); +OrderItems item = OrderItems.create("..."); +item.setQuantity(3); + +order.setItems(CdsList.delta(item)); +Update.entity(Orders_.class).entry(order); +``` + +If a direct update is unavoidable, Specify the order item that needs to be updated with a path expression: -:::warning Prefer deep updates for change-tracked entities -If you change the values of the `OrderItems` entity directly via an OData request or a CQL statement, the change log contains only one entry for the item. The change won't be associated with an order and will not be reachable through the `changes` association. While the updates of composition targets directly are possible, the change tracking feature does not attempt to resolve the parent entity by itself, it requires that either OData request or a CQL statement provide the reference to the parent, for example, `Orders`. +```java +OrderItems item = OrderItems.create("..."); +item.setQuantity(3); +Update.entity(Orders_.class, o -> o.filter(f -> f.ID().eq("...")).items()).entry(item); +``` + +Similarly, a `Delete` statement can be used to remove an item from an order: + +```java +Delete.from(Orders_.class, o -> o.filter(f -> f.ID().eq("...")).items().filter(i -> i.ID().eq("..."))); +``` + +The last segment can omit keys to indicate **bulk deletion**: + +```java +Delete.from(Orders_.class, o -> o.filter(f -> f.ID().eq("...")).items()); +``` + +The same path expression can be used in the `Insert` statement to directly add an item to a composition. + +Changes are correctly referenced to the root if the following conditions are true: +- The path expression starts at the root of the document (`Orders`, in this case). +- The path navigates only through the compositions within the same document tree. +- All segments of the path, except the last one, must include keys. + +:::warning Limitation +Avoid Direct modifications of composition items, they aren't supported by change tracking. ::: +In the following example, the item's updated changelog entry _won't_ be associated with an order: + +```java +OrderItems item = OrderItems.create("..."); +item.setQuantity(3); +Update.entity(OrderItems_.class).entry(item); +``` + +You must rewrite such statements using one of the previously illustrated ways. + ## Reacting on Changes You can write an event handler to observe the change log entries. Keep in mind that the change log entries