Clear description of my expectations versus reality
Registering a scanned class holding a certain value type property (for example: BigDecimal) and registering a custom value comparator for that value type (for example BigDecimalComparatorWithFixedEquals) via JaversBuilder should make the scanned class use the custom value comparator for that property.
In reality the scanned class seems to use for its property the JaversTypes registered early from WellKnownValueTypes (for example: BigDecimal), ignoring the custom value comparator registered via JaversBuilder.
The value type itself (here: BigDecimal) seems to hold the correct custom value comparator.
But the value type for the type mapping for the scanned class property does not hold the correct custom value comparator (in fact, in the BigDecimal case it does not hold any custom comparator at all).
Steps To Reproduce
I have a **runnable test case ** which isolates the bug and allows Javers Core Team to easily reproduce it. I have pushed this test case to my fork of this repository:
https://github.com/catautobox/javers/blob/master/javers-core/src/test/groovy/org/javers/core/cases/JaversBuilderIgnoresCustomValueComparatorForValueTypeForScannedClass.groovy
Javers' Version
6.7.1
Earlier versions are probably affected too.
Additional context
If I'm not mistaken, in org.javers.core.JaversBuilder#assembleJaversInstance
addModule(new TypeMapperModule(getContainer()));
registers WellKnownValueTypes early,
then
for (Class c : classesToScan){
typeMapper().getJaversType(c);
}
registers scanned classes (at which point their properties will share JaversTypes and custom comparators already registered at that point ),
then
mapRegisteredClasses();
registers actual custom comparators.
Registering a CustomValueComparator for a JaversType replaces the entry in the mappedTypes (here for BigDecimal itself), but the mapping for the scanned class property seems to still use a different, earlier instance of the JaveryType or CustomValueComparator.
The fact, that JaveryType mappings are being replaced makes custom value comparators "disappear" when registering custom value type adapters too:
https://github.com/catautobox/javers/blob/master/javers-core/src/test/groovy/org/javers/core/cases/JaversBuilderIgnoresCustomValueComparatorWhenRegisteringValueTypeAdapter.groovy
Maybe that's a symptom of a similar problem: custom value comparators and custom value type adapters both replacing previous JaversType mappings with unexpected side-effects, and there does not seem to be an easy way of associating an existing JaversType with one of them without having to explicitly (custom value comparator) or implicitly (custom value type adapter) replace the JaversType mapping.
Clear description of my expectations versus reality
Registering a scanned class holding a certain value type property (for example: BigDecimal) and registering a custom value comparator for that value type (for example BigDecimalComparatorWithFixedEquals) via JaversBuilder should make the scanned class use the custom value comparator for that property.
In reality the scanned class seems to use for its property the JaversTypes registered early from WellKnownValueTypes (for example: BigDecimal), ignoring the custom value comparator registered via JaversBuilder.
The value type itself (here: BigDecimal) seems to hold the correct custom value comparator.
But the value type for the type mapping for the scanned class property does not hold the correct custom value comparator (in fact, in the BigDecimal case it does not hold any custom comparator at all).
Steps To Reproduce
I have a **runnable test case ** which isolates the bug and allows Javers Core Team to easily reproduce it. I have pushed this test case to my fork of this repository:
https://github.com/catautobox/javers/blob/master/javers-core/src/test/groovy/org/javers/core/cases/JaversBuilderIgnoresCustomValueComparatorForValueTypeForScannedClass.groovy
Javers' Version
6.7.1
Earlier versions are probably affected too.
Additional context
If I'm not mistaken, in org.javers.core.JaversBuilder#assembleJaversInstance
addModule(new TypeMapperModule(getContainer()));registers WellKnownValueTypes early,
then
registers scanned classes (at which point their properties will share JaversTypes and custom comparators already registered at that point ),
then
mapRegisteredClasses();registers actual custom comparators.
Registering a CustomValueComparator for a JaversType replaces the entry in the mappedTypes (here for BigDecimal itself), but the mapping for the scanned class property seems to still use a different, earlier instance of the JaveryType or CustomValueComparator.
The fact, that JaveryType mappings are being replaced makes custom value comparators "disappear" when registering custom value type adapters too:
https://github.com/catautobox/javers/blob/master/javers-core/src/test/groovy/org/javers/core/cases/JaversBuilderIgnoresCustomValueComparatorWhenRegisteringValueTypeAdapter.groovy
Maybe that's a symptom of a similar problem: custom value comparators and custom value type adapters both replacing previous JaversType mappings with unexpected side-effects, and there does not seem to be an easy way of associating an existing JaversType with one of them without having to explicitly (custom value comparator) or implicitly (custom value type adapter) replace the JaversType mapping.