Skip Hibernate deep copy for ValueEntity.data JSON column#87
Merged
Conversation
Add @mutability(Immutability.class) to the JSONB data field so Hibernate uses reference equality instead of deserialize-compare-reserialize for dirty checking. All code paths that modify data use reference replacement (data = newData), never in-place mutation, so reference equality is correct. Profiling showed deepCopy + dirty-checking of the JSON column consumed ~50% of CPU during uploads. This eliminates both entirely — deepCopy drops to 0 samples, dirty-checking to near-zero. Wall-clock improvement of ~17% on a 4-worker rhivos import (1m36s to 1m20s) with CPU user time cut in half (2m02s to 59s).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
@Mutability(Immutability.class)toValueEntity.dataso Hibernate uses reference equality for dirty-checking instead of deserializing and comparing the full JSON treeProblem
Hibernate's
FormatMapperBasedJavaType.deepCopydeserializes and re-serializes the JSONBdatacolumn on every flush to create a snapshot for dirty comparison. Profiling showed this consumed ~50% of CPU during uploads (deepCopy + dirty-checking combined).Fix
@Mutability(Immutability.class)tells Hibernate the field value is never mutated in-place — changes are only made by replacing the reference (data = newData). Hibernate then uses the original reference as the snapshot and compares with==instead of deep tree comparison.All code paths that modify
datause reference replacement, never in-place mutation (e.g., nodata.put("key", val)), so reference equality is correct.Benchmark — rhivos-perf-comprehensive legacy import (5 runs, 4 workers, PostgreSQL)
Test plan
datain-place — all are reference replacementsexistingValue.data = newValue.datareassignment