Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 347466 - Binder - Relationship between Object and Node should be based on identity and not equality
Summary: Binder - Relationship between Object and Node should be based on identity and...
Status: RESOLVED FIXED
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Matt MacIvor CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-05-27 10:54 EDT by Blaise Doughan CLA
Modified: 2022-06-09 10:09 EDT (History)
2 users (show)

See Also:


Attachments
Proposed fix and test case (7.73 KB, patch)
2011-05-27 11:44 EDT, Matt MacIvor CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Blaise Doughan CLA 2011-05-27 10:54:02 EDT
Currently in the MOXy implementation of Binder we are maintaining a relationship between objects and nodes based on equality, this relationship should be based on identity.

This issue was raised on Stack Overflow:
- http://stackoverflow.com/questions/6146572/can-i-use-the-jaxb2-basics-plugin-with-the-moxy-jaxb-implementation-from-eclipsel
Comment 1 marcusgy CLA 2011-05-27 11:23:28 EDT
Blaise is right. Ultimately the problem is that the XMLBinderPolicy.objectsToNodes map uses the generated JAXB objects (I generated them from an xsd) directly as keys. If equals is implemented in the JAXB class with the implementation based on the state of the object, and you then change that state, then later the object with not be found in the map and the xml node lookup will fail generating the exception:

java.lang.IllegalArgumentException
	at org.eclipse.persistence.jaxb.JAXBBinder.updateXML(JAXBBinder.java:131)
	at org.eclipse.persistence.jaxb.JAXBBinder.updateXML(JAXBBinder.java:126)

I think the solution is something like wrapping the JAXB objects with another class which then references the JAXB objects and using that as the keys to XMLBinderPolicy.objectsToNodes.

An example will follow.
Comment 2 marcusgy CLA 2011-05-27 11:32:34 EDT
Referencing the example Blaise gave me at:
http://stackoverflow.com/questions/6059575/does-jaxb-support-modification-of-existing-xml-documents-without-marshalling-unma

(I haven't tried the code, just wrote it now, but it should work or should be easily modifiable to make it work).

In the Customer class, override equals and hashCode as:

public boolean equals(Object o) {
    return o != null && o.getClass().equals(getClass()) && ((Customer)o).getName().equals(getName());
}

Override hashCode as:
public int hashCode() {
    return 7;
}

Now the following code should generate the exception:

import java.io.File;
import javax.xml.bind.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;

public class BinderDemo {

    public static void main(String[] args) throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        File xml = new File("input.xml");
        Document document = db.parse(xml);

        JAXBContext jc = JAXBContext.newInstance(Customer.class);

        Binder<Node> binder = jc.createBinder();
        Customer customer = (Customer) binder.unmarshal(document);
        customer.setName("something else");
        binder.updateXML(customer);

...
Comment 3 Matt MacIvor CLA 2011-05-27 11:44:17 EDT
Created attachment 196779 [details]
Proposed fix and test case
Comment 4 Matt MacIvor CLA 2011-05-27 11:45:30 EDT
Above patch fixes the issue by switching the hashmaps used to store the object->node and node->object associations to be IdentityHashMaps.
Comment 5 Matt MacIvor CLA 2011-05-27 13:18:54 EDT
Attached patch has been checked in to SVN
Reviewed by Blaise Doughan

The fix will be available in the next EclipseLink 2.3 nightly build.
Comment 6 Eclipse Webmaster CLA 2022-06-09 10:09:47 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink