Problem
MappingConfig uses HashMap and HashSet extensively. When these collections are iterated during code generation, the order can vary between JVM runs due to hash randomization.
This causes non-deterministic output when multiple regex patterns in customAnnotationsMapping match the same type.
Example
Given this configuration:
customAnnotationsMapping = {
".*TO$" -> ["@Auditable"], // matches "ProductTO"
"Product.*" -> ["@Cached"] // also matches "ProductTO"
}
When generating ProductTO, both regex patterns match. Depending on HashMap iteration order:
Run 1: .*TO$ first, then Product.*
@Auditable
@Cached
public class ProductTO { ... }
Run 2: Product.* first, then .*TO$
@Cached
@Auditable
public class ProductTO { ... }
The annotations are semantically identical, but byte-for-byte different.
Impact on Build Caching
Cache hits: Work correctly — Gradle retrieves the exact cached output regardless of HashMap ordering.
Cache misses: Can produce different outputs on each run, making the cache unreliable when:
- Cache is frequently cleared
- Multiple developers share a cache
- Byte-for-byte reproducibility is required
Options to Fix
Option 1: Sort during iteration
Sort map entries by key during code generation:
map.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.forEach(entry -> { ... });
Option 2: Use sorted collections
Replace HashMap/HashSet with TreeMap/TreeSet in MappingConfig:
private Map<String, List<String>> customAnnotationsMapping = new TreeMap<>();
Option 3: Sort before code generation
Collect items into sorted lists before generating code.
Affected Code
src/main/java/io/github/besi97/graphql/codegen/mapper/AnnotationsMapper.java:153 — iterates customAnnotationsMapping.entrySet()
src/main/java/io/github/besi97/graphql/codegen/model/MappingConfig.java — uses HashMap and HashSet for configuration properties
- Additional iteration points throughout the codebase (25 occurrences found)
Problem
MappingConfigusesHashMapandHashSetextensively. When these collections are iterated during code generation, the order can vary between JVM runs due to hash randomization.This causes non-deterministic output when multiple regex patterns in
customAnnotationsMappingmatch the same type.Example
Given this configuration:
When generating
ProductTO, both regex patterns match. Depending on HashMap iteration order:Run 1:
.*TO$first, thenProduct.*Run 2:
Product.*first, then.*TO$The annotations are semantically identical, but byte-for-byte different.
Impact on Build Caching
Cache hits: Work correctly — Gradle retrieves the exact cached output regardless of HashMap ordering.
Cache misses: Can produce different outputs on each run, making the cache unreliable when:
Options to Fix
Option 1: Sort during iteration
Sort map entries by key during code generation:
Option 2: Use sorted collections
Replace
HashMap/HashSetwithTreeMap/TreeSetinMappingConfig:Option 3: Sort before code generation
Collect items into sorted lists before generating code.
Affected Code
src/main/java/io/github/besi97/graphql/codegen/mapper/AnnotationsMapper.java:153— iteratescustomAnnotationsMapping.entrySet()src/main/java/io/github/besi97/graphql/codegen/model/MappingConfig.java— usesHashMapandHashSetfor configuration properties