From 9f05546972732f31b89805017664561cab28aaf3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 13:24:25 +0000 Subject: [PATCH 1/3] Initial plan From c465134d8fc98d041713e335cade7cd37bb43ce2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 13:27:58 +0000 Subject: [PATCH 2/3] Add readItem() / CosmosItemResponse unwrapping guidance to sdk-java-content-response rule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #27: Code treating CosmosItemResponse as T directly — missing .getItem() call caused type mismatch compilation errors at every readItem() call site (~30% of raw-SDK runs). - Updated rule title, tags, and impact description for broader scope - Added new leading section with incorrect/correct examples (sync + async) - Recompiled AGENTS.md - Updated IMPROVEMENTS-LOG.md Co-authored-by: TheovanKraay <24420698+TheovanKraay@users.noreply.github.com> Agent-Logs-Url: https://github.com/AzureCosmosDB/cosmosdb-agent-kit/sessions/e4d08924-00f7-452c-b90c-987c2eafd29c --- skills/cosmosdb-best-practices/AGENTS.md | 70 ++++++++++++++++--- .../rules/sdk-java-content-response.md | 70 ++++++++++++++++--- testing-v2/IMPROVEMENTS-LOG.md | 14 ++++ 3 files changed, 138 insertions(+), 16 deletions(-) diff --git a/skills/cosmosdb-best-practices/AGENTS.md b/skills/cosmosdb-best-practices/AGENTS.md index 18741e95..f26f0a4e 100644 --- a/skills/cosmosdb-best-practices/AGENTS.md +++ b/skills/cosmosdb-best-practices/AGENTS.md @@ -55,7 +55,7 @@ Performance optimization and best practices guide for Azure Cosmos DB applicatio - 4.6 [Configure SSL and connection mode for Cosmos DB Emulator](#46-configure-ssl-and-connection-mode-for-cosmos-db-emulator) - 4.7 [Use ETags for optimistic concurrency on read-modify-write operations](#47-use-etags-for-optimistic-concurrency-on-read-modify-write-operations) - 4.8 [Configure Excluded Regions for Dynamic Failover](#48-configure-excluded-regions-for-dynamic-failover) - - 4.9 [Enable content response on write operations in Java SDK](#49-enable-content-response-on-write-operations-in-java-sdk) + - 4.9 [Unwrap CosmosItemResponse and enable content response in Java SDK](#49-unwrap-cosmositemresponse-and-enable-content-response-in-java-sdk) - 4.10 [Use dependent @Bean methods for Cosmos DB initialization in Spring Boot](#410-use-dependent-bean-methods-for-cosmos-db-initialization-in-spring-boot) - 4.11 [Spring Boot and Java version compatibility for Cosmos DB SDK](#411-spring-boot-and-java-version-compatibility-for-cosmos-db-sdk) - 4.12 [Configure local development environment to avoid cloud connection conflicts](#412-configure-local-development-environment-to-avoid-cloud-connection-conflicts) @@ -3589,11 +3589,64 @@ var outageOptions = new ItemRequestOptions Reference: [Performance tips - .NET SDK Excluded Regions](https://learn.microsoft.com/en-us/azure/cosmos-db/performance-tips-dotnet-sdk-v3#excluded-regions) Reference: [Performance tips - Java SDK Excluded Regions](https://learn.microsoft.com/en-us/azure/cosmos-db/performance-tips-java-sdk-v4#excluded-regions) -### 4.9 Enable content response on write operations in Java SDK +### 4.9 Unwrap CosmosItemResponse and enable content response in Java SDK -**Impact: MEDIUM** (ensures created/updated documents are returned from write operations) +**Impact: MEDIUM** (prevents type errors from missing getItem() on reads and null content on writes) -## Enable Content Response on Write Operations (Java) +## Unwrap CosmosItemResponse with getItem() (Java) + +All Cosmos DB Java SDK point-read and write operations (`readItem`, `createItem`, `upsertItem`, `replaceItem`) return `CosmosItemResponse`, **not** `T` directly. You must call `.getItem()` to extract the entity. Treating the response wrapper as the entity causes compilation errors or incorrect behavior. + +### Always unwrap readItem() with getItem() + +`readItem()` always returns `CosmosItemResponse`. You must call `.getItem()` to get the actual document. + +**Incorrect — treating CosmosItemResponse as the entity:** + +```java +// ❌ WRONG: readItem returns CosmosItemResponse, NOT Player +public Player getPlayer(String playerId) { + Player player = container.readItem( + playerId, new PartitionKey(playerId), Player.class); // ❌ Compilation error! + return player; +} +``` + +```java +// ❌ WRONG (async): Mono> is not Mono +public Mono getPlayer(String playerId) { + return container.readItem( + playerId, new PartitionKey(playerId), Player.class); // ❌ Type mismatch! +} +``` + +**Correct — unwrap with getItem():** + +```java +// ✅ CORRECT: Call getItem() to extract the entity from the response +public Player getPlayer(String playerId) { + CosmosItemResponse response = container.readItem( + playerId, new PartitionKey(playerId), Player.class); + return response.getItem(); // ✅ Returns the Player entity +} +``` + +```java +// ✅ CORRECT (async): Map the response to extract the entity +public Mono getPlayer(String playerId) { + return container.readItem( + playerId, new PartitionKey(playerId), Player.class) + .map(response -> response.getItem()); // ✅ Unwrap to Player +} +``` + +> **Why this matters:** `CosmosItemResponse` is a wrapper that holds the entity (`getItem()`), +> request charge (`getRequestCharge()`), ETag (`getETag()`), headers, and diagnostics. +> Assigning the response directly to a variable of type `T` is a compile-time error in +> synchronous code and a type-mismatch error in reactive chains. This affects `readItem`, +> `createItem`, `upsertItem`, and `replaceItem` — all return `CosmosItemResponse`. + +### Enable Content Response on Write Operations By default, the Java Cosmos DB SDK does **not** return the document content after create/upsert operations. The response contains only metadata (headers, diagnostics) but the `getItem()` method returns null. You must explicitly enable content response if you need the created document. @@ -3693,11 +3746,12 @@ for (Order order : ordersToInsert) { Enabling content response does NOT increase RU cost - the document is already fetched server-side for the write operation. It only affects the response payload size over the network. **Key Points:** -- Java SDK returns null by default for created/upserted items -- Enable `contentResponseOnWriteEnabled(true)` to get documents back +- `readItem()`, `createItem()`, `upsertItem()`, and `replaceItem()` all return `CosmosItemResponse` — always call `.getItem()` to get `T` +- In reactive/async code, use `.map(response -> response.getItem())` to unwrap the entity from the `Mono` +- Java SDK returns null from `getItem()` by default for created/upserted items — enable `contentResponseOnWriteEnabled(true)` to get documents back after writes - Can be set at client level (all operations) or per-request -- Spring Data Cosmos handles this automatically -- Disable for high-throughput scenarios where response content is not needed +- Spring Data Cosmos handles both unwrapping and content response automatically +- Disable content response for high-throughput scenarios where response content is not needed Reference: [Azure Cosmos DB Java SDK best practices](https://learn.microsoft.com/azure/cosmos-db/nosql/best-practice-java) diff --git a/skills/cosmosdb-best-practices/rules/sdk-java-content-response.md b/skills/cosmosdb-best-practices/rules/sdk-java-content-response.md index f2861d64..99088939 100644 --- a/skills/cosmosdb-best-practices/rules/sdk-java-content-response.md +++ b/skills/cosmosdb-best-practices/rules/sdk-java-content-response.md @@ -1,11 +1,64 @@ --- -title: Enable content response on write operations in Java SDK +title: Unwrap CosmosItemResponse and enable content response in Java SDK impact: MEDIUM -impactDescription: ensures created/updated documents are returned from write operations -tags: sdk, java, content-response, create, upsert +impactDescription: prevents type errors from missing getItem() on reads and null content on writes +tags: sdk, java, content-response, readItem, create, upsert, getItem --- -## Enable Content Response on Write Operations (Java) +## Unwrap CosmosItemResponse with getItem() (Java) + +All Cosmos DB Java SDK point-read and write operations (`readItem`, `createItem`, `upsertItem`, `replaceItem`) return `CosmosItemResponse`, **not** `T` directly. You must call `.getItem()` to extract the entity. Treating the response wrapper as the entity causes compilation errors or incorrect behavior. + +### Always unwrap readItem() with getItem() + +`readItem()` always returns `CosmosItemResponse`. You must call `.getItem()` to get the actual document. + +**Incorrect — treating CosmosItemResponse as the entity:** + +```java +// ❌ WRONG: readItem returns CosmosItemResponse, NOT Player +public Player getPlayer(String playerId) { + Player player = container.readItem( + playerId, new PartitionKey(playerId), Player.class); // ❌ Compilation error! + return player; +} +``` + +```java +// ❌ WRONG (async): Mono> is not Mono +public Mono getPlayer(String playerId) { + return container.readItem( + playerId, new PartitionKey(playerId), Player.class); // ❌ Type mismatch! +} +``` + +**Correct — unwrap with getItem():** + +```java +// ✅ CORRECT: Call getItem() to extract the entity from the response +public Player getPlayer(String playerId) { + CosmosItemResponse response = container.readItem( + playerId, new PartitionKey(playerId), Player.class); + return response.getItem(); // ✅ Returns the Player entity +} +``` + +```java +// ✅ CORRECT (async): Map the response to extract the entity +public Mono getPlayer(String playerId) { + return container.readItem( + playerId, new PartitionKey(playerId), Player.class) + .map(response -> response.getItem()); // ✅ Unwrap to Player +} +``` + +> **Why this matters:** `CosmosItemResponse` is a wrapper that holds the entity (`getItem()`), +> request charge (`getRequestCharge()`), ETag (`getETag()`), headers, and diagnostics. +> Assigning the response directly to a variable of type `T` is a compile-time error in +> synchronous code and a type-mismatch error in reactive chains. This affects `readItem`, +> `createItem`, `upsertItem`, and `replaceItem` — all return `CosmosItemResponse`. + +### Enable Content Response on Write Operations By default, the Java Cosmos DB SDK does **not** return the document content after create/upsert operations. The response contains only metadata (headers, diagnostics) but the `getItem()` method returns null. You must explicitly enable content response if you need the created document. @@ -105,10 +158,11 @@ for (Order order : ordersToInsert) { Enabling content response does NOT increase RU cost - the document is already fetched server-side for the write operation. It only affects the response payload size over the network. **Key Points:** -- Java SDK returns null by default for created/upserted items -- Enable `contentResponseOnWriteEnabled(true)` to get documents back +- `readItem()`, `createItem()`, `upsertItem()`, and `replaceItem()` all return `CosmosItemResponse` — always call `.getItem()` to get `T` +- In reactive/async code, use `.map(response -> response.getItem())` to unwrap the entity from the `Mono` +- Java SDK returns null from `getItem()` by default for created/upserted items — enable `contentResponseOnWriteEnabled(true)` to get documents back after writes - Can be set at client level (all operations) or per-request -- Spring Data Cosmos handles this automatically -- Disable for high-throughput scenarios where response content is not needed +- Spring Data Cosmos handles both unwrapping and content response automatically +- Disable content response for high-throughput scenarios where response content is not needed Reference: [Azure Cosmos DB Java SDK best practices](https://learn.microsoft.com/azure/cosmos-db/nosql/best-practice-java) diff --git a/testing-v2/IMPROVEMENTS-LOG.md b/testing-v2/IMPROVEMENTS-LOG.md index 2f5d0cb0..aae40468 100644 --- a/testing-v2/IMPROVEMENTS-LOG.md +++ b/testing-v2/IMPROVEMENTS-LOG.md @@ -18,6 +18,20 @@ Each improvement entry should include: ## Improvements +#### 2026-03-23: Rule Enhancement — readItem() / CosmosItemResponse unwrapping guidance (Issue #27) + +- **Scenario**: gaming-leaderboard +- **Iteration**: P01/R02, P01/R04, P03/R03 (~30% of raw-SDK runs) +- **Issue**: Code treats `CosmosItemResponse` as `T` directly — missing the `.getItem()` call to extract the actual entity value. This causes type mismatch compilation errors in every `readItem()` call site. The existing `sdk-java-content-response` rule only covered write operations (`contentResponseOnWriteEnabled`), not read-side unwrapping. +- **Improvement**: Enhanced existing rule `sdk-java-content-response.md` to cover both read and write operations: + 1. Added new leading section "Always unwrap readItem() with getItem()" with incorrect/correct examples for both sync and async patterns + 2. Updated title from "Enable content response on write operations" to "Unwrap CosmosItemResponse and enable content response in Java SDK" + 3. Updated tags and impact description to reflect broader scope + 4. Updated Key Points to emphasize that all CRUD operations return `CosmosItemResponse` +- **Files Modified**: + - `skills/cosmosdb-best-practices/rules/sdk-java-content-response.md` (enhanced) + - `skills/cosmosdb-best-practices/AGENTS.md` (recompiled) + #### 2026-03-12: New Rules — Parameterized TOP and Composite Index Directions - **Scenario**: gaming-leaderboard From d0cbf8ba1a7102f58a407a3c85dfc455105f8ea7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 13:51:18 +0000 Subject: [PATCH 3/3] =?UTF-8?q?Remove=20IMPROVEMENTS-LOG.md=20update=20?= =?UTF-8?q?=E2=80=94=20log=20is=20only=20for=20testing=20framework=20chang?= =?UTF-8?q?es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: TheovanKraay <24420698+TheovanKraay@users.noreply.github.com> Agent-Logs-Url: https://github.com/AzureCosmosDB/cosmosdb-agent-kit/sessions/728b5aea-f2c7-4e91-9d77-cefe9ac0a9b9 --- testing-v2/IMPROVEMENTS-LOG.md | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/testing-v2/IMPROVEMENTS-LOG.md b/testing-v2/IMPROVEMENTS-LOG.md index aae40468..2f5d0cb0 100644 --- a/testing-v2/IMPROVEMENTS-LOG.md +++ b/testing-v2/IMPROVEMENTS-LOG.md @@ -18,20 +18,6 @@ Each improvement entry should include: ## Improvements -#### 2026-03-23: Rule Enhancement — readItem() / CosmosItemResponse unwrapping guidance (Issue #27) - -- **Scenario**: gaming-leaderboard -- **Iteration**: P01/R02, P01/R04, P03/R03 (~30% of raw-SDK runs) -- **Issue**: Code treats `CosmosItemResponse` as `T` directly — missing the `.getItem()` call to extract the actual entity value. This causes type mismatch compilation errors in every `readItem()` call site. The existing `sdk-java-content-response` rule only covered write operations (`contentResponseOnWriteEnabled`), not read-side unwrapping. -- **Improvement**: Enhanced existing rule `sdk-java-content-response.md` to cover both read and write operations: - 1. Added new leading section "Always unwrap readItem() with getItem()" with incorrect/correct examples for both sync and async patterns - 2. Updated title from "Enable content response on write operations" to "Unwrap CosmosItemResponse and enable content response in Java SDK" - 3. Updated tags and impact description to reflect broader scope - 4. Updated Key Points to emphasize that all CRUD operations return `CosmosItemResponse` -- **Files Modified**: - - `skills/cosmosdb-best-practices/rules/sdk-java-content-response.md` (enhanced) - - `skills/cosmosdb-best-practices/AGENTS.md` (recompiled) - #### 2026-03-12: New Rules — Parameterized TOP and Composite Index Directions - **Scenario**: gaming-leaderboard