SQiShER / java-object-diff

Library to diff and merge Java objects with ease
http://sqisher.github.io/java-object-diff/
Apache License 2.0
945 stars 178 forks source link

Where is the correct place for specialization #145

Closed olafurbergs closed 8 years ago

olafurbergs commented 8 years ago

Hi,

I hope you can help me with this, I am diffing 2 objects which have been unmarshalled using jaxb.

I am having problem with types of https://docs.oracle.com/javase/7/docs/api/javax/xml/datatype/Duration.html

which need to be instantiated with https://docs.oracle.com/javase/7/docs/api/javax/xml/datatype/DatatypeFactory.html

When running node.canonicalSet( merged, node.canonicalGet( newInformation ) ); I get : de.danielbechler.diff.instantiation.TypeInstantiationException thrown due to : Failed to create instance of type 'class com.sun.org.apache.xerces.internal.jaxp.datatype.DurationImpl'. Reason: Type doesn't have a public non-arg constructur

How do I get around this?

SQiShER commented 8 years ago

Hi,

you can provide a custom InstanceFactory like so:

InstanceFactory instanceFactory = new InstanceFactory() {
    @Override
    Object newInstanceOfType(Class<?> type) {
        if (Duration.isAssignableFrom(type)) {
            return DatatypeFactory.newInstance().newDuration(0);
        }
        return null
    }
}

ObjectDiffer objectDiffer = ObjectDifferBuilder.startBuilding()
    .introspection().setInstanceFactory(instanceFactory).and()
    .build()

However, I don't think it will help in your case, because the library is trying to instantiate the Duration because you are trying to assign a new value to one of its properties. This will ultimately fail, because Duration is an immutable data structure.

I think what you really want to do is to mark Duration as an equals-only type, so that the ObjectDiffer won't look at it's properties and only use its equals method to determine whether it has changed. This way canonicalSet will simply replace the entire Duration instance, instead of trying to modify it.

Hope this helps! Keep me posted. :wink: