Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ClassCastException: MissingProperty cannot be cast to java.lang.Double #935

Closed
mdii opened this issue Feb 4, 2020 · 6 comments
Closed

ClassCastException: MissingProperty cannot be cast to java.lang.Double #935

mdii opened this issue Feb 4, 2020 · 6 comments

Comments

@mdii
Copy link
Contributor

@mdii mdii commented Feb 4, 2020

Hello, we have a use case that needs a custom comparator for Double values. However in some cases we get the following exception:

java.lang.ClassCastException: org.javers.core.metamodel.property.MissingProperty cannot be cast to java.lang.Double
	at org.javers.core.metamodel.type.CustomValueComparatorNullSafe.equals(CustomValueComparatorNullSafe.java:29)
	at org.javers.core.metamodel.type.PrimitiveOrValueType.equals(PrimitiveOrValueType.java:32)
	at org.javers.core.diff.appenders.ValueChangeAppender.calculateChanges(ValueChangeAppender.java:34)
	at org.javers.core.diff.appenders.ValueChangeAppender.calculateChanges(ValueChangeAppender.java:10)
	at org.javers.core.diff.DiffFactory.appendChanges(DiffFactory.java:153)
	at org.javers.core.diff.DiffFactory.appendPropertyChanges(DiffFactory.java:143)
....

I managed to reproduce it in the following test case.

class CustomValueComparatorCase extends Specification {
    class Parent {}

    class Child1 extends Parent {
        String prop1
    }

    class Child2 extends Parent {
        Double prop2
    }

    class Container {
        Map<String, Parent> map = new HashMap<>()
    }

    class CustomDoubleComparator implements CustomValueComparator<Double> {
        @Override
        boolean equals(Double a, Double b) {
            return round(a) == round(b)
        }

        @Override
        String toString(Double value) {
            return round(value).toString()
        }

        private BigDecimal round(Double val) {
            return NumberUtils.toScaledBigDecimal(val, 4, RoundingMode.HALF_UP)
        }
    }

    def "should compare map values using their concrete type"() {
        given:
        def javers = JaversBuilder.javers()
                .registerValue(Double.class, new CustomDoubleComparator())
                .build()

        when:
        Parent c1 = new Child1(prop1: "Hi")
        Parent c2 = new Child2(prop2: 1.2)


        Container container1 = new Container()
        container1.map.put("key", c1)

        Container container2 = new Container()
        container2.map.put("key", c2)

        def diff = javers.compare(container1, container2)

        then:
        diff.changes.size() > 0

        println(diff.changes)
    }
}

It seems that Javers sees the values in the map as Parent type not the concrete type.
If I change Map<String, Parent> map to Map<String, Object> map then the test passes.
If I keep Map<String, Parent> map and compare the maps directly like javers.compare(container1.map, container2.map) then the test passes.

Would it be possible to avoid this exception?

@bartoszwalacik
Copy link
Member

@bartoszwalacik bartoszwalacik commented Feb 4, 2020

@mdii
Copy link
Contributor Author

@mdii mdii commented Feb 6, 2020

Done #936

bartoszwalacik added a commit that referenced this issue Feb 6, 2020
@bartoszwalacik
Copy link
Member

@bartoszwalacik bartoszwalacik commented Feb 6, 2020

thanks for reporting, fortunately, that's easy to fix

@mdii
Copy link
Contributor Author

@mdii mdii commented Feb 7, 2020

Thanks for the fix. I am still wandering about the behavior that I reported:

It seems that Javers sees the values in the map as Parent type not the concrete type.
If I change Map<String, Parent> map to Map<String, Object> map then the test passes.
If I keep Map<String, Parent> map and compare the maps directly like javers.compare(container1.map, container2.map) then the test passes.

@bartoszwalacik
Copy link
Member

@bartoszwalacik bartoszwalacik commented Feb 7, 2020

Fixed in 5.8.9, try now (map was not the cause) but handling MISSING_PROPERTY in CustomValueComparator

@mdii
Copy link
Contributor Author

@mdii mdii commented Feb 7, 2020

Thank you!

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

No branches or pull requests

2 participants