Skip to content

Comments

Remove unnecessary intermediate String deserialization of document bodies#2122

Draft
emilienbev wants to merge 6 commits intomainfrom
UseRawBytes
Draft

Remove unnecessary intermediate String deserialization of document bodies#2122
emilienbev wants to merge 6 commits intomainfrom
UseRawBytes

Conversation

@emilienbev
Copy link
Collaborator

@emilienbev emilienbev commented Feb 19, 2026

Fixes #2121

  • You have read the Spring Data contribution guidelines.
  • There is a ticket in the bug tracker for the project in our JIRA.
  • You use the code formatters provided here and have them applied to your changes. Don’t submit any formatting related changes.
  • You submit test cases (unit or integration tests) that back your changes.
  • You added yourself as author in the headers of the classes you touched. Amend the date range in the Apache license header if needed. For new types, add the license header (copy from another file and set the current year only).

… favour of the raw bytes

Signed-off-by: Emilien Bevierre <emilien.bevierre@couchbase.com>
…immediately after subscribe(), before the document has potentially been saved.

Signed-off-by: Emilien Bevierre <emilien.bevierre@couchbase.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses issue #2121 by eliminating an unnecessary intermediate String conversion when decoding KV document bodies, enabling decoding directly from raw response bytes (notably for reactive KV operations) while keeping string-based decoding available.

Changes:

  • Add byte[] decode paths across template support APIs and internal decode flow (TemplateSupport / ReactiveTemplateSupportAbstractTemplateSupportTranslationService).
  • Update reactive KV operations (e.g., find-by-id, range scan, replicas) to pass contentAsBytes() instead of converting to String.
  • Extend Jackson translation to decode directly from byte[] and add tests validating byte-based decoding (including non-ASCII content).

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/test/java/org/springframework/data/couchbase/repository/query/ReactiveCouchbaseRepositoryQueryCollectionIntegrationTests.java Adjusts reactive test flow to block for completion (avoids async subscribe).
src/test/java/org/springframework/data/couchbase/core/convert/translation/JacksonTranslationServiceTests.java Adds coverage for decoding from UTF-8 bytes (ASCII + non-ASCII).
src/main/java/org/springframework/data/couchbase/core/convert/translation/TranslationService.java Adds decode(byte[], ...) default overload to support byte-based decoding.
src/main/java/org/springframework/data/couchbase/core/convert/translation/JacksonTranslationService.java Implements direct byte[] parsing via Jackson JsonParser.
src/main/java/org/springframework/data/couchbase/core/TemplateSupport.java Adds byte[] overload for entity decoding (sync template support).
src/main/java/org/springframework/data/couchbase/core/ReactiveTemplateSupport.java Adds byte[] overload for entity decoding (reactive template support).
src/main/java/org/springframework/data/couchbase/core/ReactiveRangeScanOperationSupport.java Uses contentAsBytes() to avoid intermediate String creation.
src/main/java/org/springframework/data/couchbase/core/ReactiveFindFromReplicasByIdOperationSupport.java Uses contentAsBytes() for replica reads.
src/main/java/org/springframework/data/couchbase/core/ReactiveFindByIdOperationSupport.java Uses contentAsBytes() across get variants (touch/lock/get/tx path).
src/main/java/org/springframework/data/couchbase/core/ReactiveCouchbaseTemplateSupport.java Implements reactive byte[] decodeEntity overload.
src/main/java/org/springframework/data/couchbase/core/NonReactiveSupportWrapper.java Bridges reactive byte[] decode to non-reactive support.
src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplateSupport.java Implements sync byte[] decodeEntity overload.
src/main/java/org/springframework/data/couchbase/core/AbstractTemplateSupport.java Adds byte[] decodeEntityBase path and refactors shared decode/finalize steps.
.gitignore Ignores src/test/resources/integration.local.properties.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

emilienbev and others added 2 commits February 19, 2026 16:55
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Emilien Bevierre <44171454+emilienbev@users.noreply.github.com>
…te[] ...) (back to String).

Ensure that if both parsing and close throw, the close exception is suppressed rather than masking the original error.

Signed-off-by: Emilien Bevierre <emilien.bevierre@couchbase.com>
* @return a properly populated document to work with.
*/
default CouchbaseStorable decode(byte[] source, CouchbaseStorable target) {
return decode(new String(source, StandardCharsets.UTF_8), target);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeing new String(…, StandardCharsets.UTF_8) in various places hints for having a utility method somewhere. ByteUtils.toString(…) could be a good startingpoint.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Mark, pushed this in a7d84f1 .

* @return the decoded structure.
*/
@Override
public final CouchbaseStorable decode(final byte[] source, final CouchbaseStorable target) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final arguments and in variable declarations (further down below in the pull request) is rather noise and distracts from reading code. This is more of an observation.

Copy link

@onobc onobc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋🏻 @emilienbev
Great work! Thank you for the excellent detail in the issue and the PR description.

I have one request that spans multiple files... do you mind moving your @ author... tags to the end of the list as we typically add in history order (i.e. the original author of the source is the first entry).

Re-order author tags correctly
Remove excessive final modifiers

Signed-off-by: Emilien Bevierre <emilien.bevierre@couchbase.com>
Adjust comments

Signed-off-by: Emilien Bevierre <emilien.bevierre@couchbase.com>
Copy link

@onobc onobc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work @emilienbev - looks good to me. I have a comment around logging and using String#formatted but you can do what you want w/ that one.

The only other comment I have was mentioned by Mark - we typically don't add final to anything other immutable fields that are set in the constructor.

throw new CouchbaseException(TemplateUtils.SELECT_ID + " was null. Either use #{#n1ql.selectEntity} or project "
+ TemplateUtils.SELECT_ID);
throw new CouchbaseException(
TemplateUtils.SELECT_ID + " was null. Either use #{#n1ql.selectEntity} or project "
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have found String#formatted to help w/ the readability of logging statements like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: waiting-for-triage An issue we've not yet triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Documents are deserialized to String before final entity class

4 participants