I experimented a little further with this. It seems that when you marshall
one object like this (marshaller.marshal(parent)), you get the elements
in-inline and no references are used even if you configure that in your
mapping-xml using identity and reference attributes.
However, if you marshall an object (such as List) that contains both
referred objects, references are used.
<?xml version="1.0" encoding="UTF-8"?>
<container>
<objects xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="parent">
<id>111</id>
<child>1</child>
</objects>
<objects xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="child">
<id>1</id>
<name>Jack</name>
<age>10</age>
<parent>111</parent>
</objects>
</container>
This was accomplished with the modified versions of the classes and mapping
file. I had to use a special "container" object in order to get castor agree
to marshall the list:
public class Container {
List objects = new ArrayList();
// accessors...
}
public class Parent {
private int id;
private Child child;
// accessors...
}
public class Child {
private int id;
private String name;
private Parent parent;
private int age;
// accessors...
}
<class name="tests.Container" auto-complete="true">
</class>
<class name="tests.Parent" identity="id">
<map-to xml="parent"/>
<field name="id" type="int">
<bind-xml name="id" node="element" />
</field>
<field name="child" type="tests.Child">
<bind-xml name="child" node="element" reference="true" />
</field>
</class>
<class name="tests.Child" identity="id">
<map-to xml="child"/>
<field name="id" type="int">
<bind-xml name="id" node="element" />
</field>
<field name="name" type="java.lang.String">
<bind-xml name="name" node="element" />
</field>
<field name="age" type="int" >
<bind-xml name="age" node="element" />
</field>
<field name="parent" type="tests.Parent">
<bind-xml name="parent" node="element" reference="true"/>
</field>
</class>
So, the marshalling _seems_ to work ok. However, unmarshalling still
crashes. When I try to unmarshall the XML I get:
Caused by: org.exolab.castor.xml.MarshalException: unable to resolve
reference: 1{File: [not available]; line: 13; column: 13}
at
org.exolab.castor.xml.Unmarshaller.convertSAXExceptionToMarshalException(Unmarshaller.java:794)
at
org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:760)
at
org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:626)
at
fi.ains.jp.model.service.tests.FactoryTest.loadParentList(FactoryTest.java:151)
... 30 more
Caused by: 1. ValidationException: unable to resolve reference: 1
2. ValidationException: unable to resolve reference: 111
at
org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:919)
at
org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:1176)
at
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:601)
at
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1774)
at
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2930)
at
com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
at
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
at
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807)
at
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
at
com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107)
at
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
at
com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at
org.exolab.castor.xml.Unmarshaller.unmarshal(Unmarshaller.java:748)
... 32 more
Can anyone help me to get this example working? To me this seems a dead
simple application of the references, so if they do indeed work this should
not be this hard.
Although I'm starting to wonder if references are even supported in XML
binding after all since the doc at http://www.castor.org/xml-mapping.html
says that "identity - Used with Castor JDO only"
jimmi4664 wrote:
>
> Any ideas on this? How could I marshal / unmarshal the example
> parent-child relation with castor?
>
>
>
>
> jimmi4664 wrote:
>>
>> Are you suggesting that I should define the mapping differently instead
>> of using mapping.xml file?
>>
>> For now I preferred experimenting further with the original mapping.xml
>> path and thought about the possibility of using one field as the "unique
>> identifier". I think I could use it even though I don't have a pure
>> "unique identifier" for my class. I can get the example from
>> http://www.castor.org/how-to-use-references-in-xml.html working. It still
>> works quite weird when I try this example that follows my actual needs in
>> concept:
>>
>> public class Child {
>> private String name;
>> private Parent parent;
>> private int age;
>> // getters and setters
>> }
>>
>> public class Parent {
>> private int id;
>> private Child child;
>> // getters and setters
>> }
>>
>> mapping.xml:
>>
>> <class name="tests.Parent" identity="id">
>> <map-to xml="parent"/>
>> <field name="id" type="int">
>> <bind-xml name="id" node="element" />
>> </field>
>> <field name="child" type="tests.Child">
>> <bind-xml name="child" node="element"/>
>> </field>
>> </class>
>>
>> <class name="tests.Child">
>> <map-to xml="child"/>
>> <field name="name" type="java.lang.String">
>> <bind-xml name="name" node="element" />
>> </field>
>> <field name="age" type="int" >
>> <bind-xml name="age" node="element" />
>> </field>
>> <field name="parent" type="tests.Parent">
>> <bind-xml name="parent" node="element" reference="true"/>
>> </field>
>> </class>
>>
>> marshalling:
>>
>> Parent p = new Parent();
>> Child c = new Child();
>> p.setChild(c);
>> p.setId(111);
>> c.setName("Jack");
>> c.setAge(10);
>> c.setParent(p);
>> ....
>> marshaller.marshal(p);
>>
>> =>
>>
>> <?xml version="1.0" encoding="UTF-8"?>
>> <parent>
>> <id>111</id>
>> <child>
>> <name>Jack</name>
>> <age>10</age>
>> </child>
>> </parent>
>>
>> So the child's reference to parent is missing, and Child.parent is null
>> when unmarshalled.
>>
>>
>>
>>
>>
>> Werner Guttmann-6 wrote:
>>>
>>> Hi,
>>>
>>> jimmi4664 wrote:
>>>> There's no requirements on the XML, other than I want to persist my
>>>> objects
>>>> as an XML file, and be able to reconstruct them later. The resulting
>>>> XML can
>>>> (pretty much) be whatever castor would like it to be.
>>>>
>>>> So, -for example- following XML would be fine:
>>>>
>>>> <person>
>>>> <name>asdfas</name>
>>>> <castor-generated-id>4652</castor-generated-id>
>>>> <cars>
>>>> <car>
>>>> <license-plate>34243</license-plate>
>>>> <owner-castor-generated-id>4652</owner-castor-generated-id >
>>>> </car>
>>>> <car>
>>>> <license-plate>111221</license-plate>
>>>> < owner-castor-generated-id >4652</owner-castor-generated-id >
>>>> </car>
>>>> </cars>
>>>> </person>
>>>>
>>>> The fact is that I don't have "id" field in my objects. They are pure
>>>> POJOs
>>>> and just have object references to one another. Castor _could_
>>>> theoretically
>>>> cope with this requirement by just using object identity and generating
>>>> correct "id" fields internally.
>>> Yes and no. If you were to use XML schemas to define your contracts,
>>> you'd be using <xsd:ID/> and <xsd:IDREF/> types to denote that you are
>>> dealing with (cyclic) references. Have a look at e.g. the XML Schema
>>> Primer [1] first, and we'll continue our conversation after you have
>>> familiarized yourself with the concepts presented therein.
>>>
>>> Okay ?
>>>
>>> Regards
>>> Werner
>>>
>>> [1] http://www.w3.org/TR/xmlschema-0/
>>>
>>>>
>>>> I don't know if this is available, or do I need to create artificial ID
>>>> fields in my POJOs?
>>>>
>>>> Another alternative is to forget about Car.owner in the mapping and
>>>> just fix
>>>> it manually after unmarshalling the objects.
>>>>
>>>>
>>>> Werner Guttmann-6 wrote:
>>>>> Hi,
>>>>>
>>>>> how does/should your XML actually look like ?
>>>>>
>>>>> Regards
>>>>> Werner
>>>>>
>>>>> jimmi4664 wrote:
>>>>>> That seems to assume I would have a unique identifier in my object.
>>>>>> There's
>>>>>> actually no good field in my example that could be used like that,
>>>>>> and
>>>>>> what's worse my real world case does not have that either.
>>>>>>
>>>>>> So I believe if I want to make castor set the references correctly, I
>>>>>> need
>>>>>> to add some artificial ID field to my classes?
>>>>>>
>>>>>>
>>>>>>
>>>>>> Ralf Joachim-2 wrote:
>>>>>>> Hi Janne,
>>>>>>>
>>>>>>> when using mapping usage of references as explained in:
>>>>>>>
>>>>>>> http://www.castor.org/how-to-use-references-in-xml.html
>>>>>>>
>>>>>>> may help. If you generate code out of XSD you may need to take a
>>>>>>> look at
>>>>>>> xs:id and xs:idref to handle this.
>>>>>>>
>>>>>>> Having said that I never used that myself.
>>>>>>>
>>>>>>> Regards
>>>>>>> Ralf
>>>>>>>
>>>>>>> jimmi4664 schrieb:
>>>>>>>> I tried autocreating mapping file for a simple example using
>>>>>>>> MappingTool
>>>>>>>> to
>>>>>>>> maybe give a hint on how to do this:
>>>>>>>>
>>>>>>>> public class Owner {
>>>>>>>> private String name;
>>>>>>>> private ArrayList<Vehicle> vehicles = new ArrayList<Vehicle>();
>>>>>>>>
>>>>>>>> public String getName() {
>>>>>>>> return name;
>>>>>>>> }
>>>>>>>>
>>>>>>>> public void setName(String name) {
>>>>>>>> this.name = name;
>>>>>>>> }
>>>>>>>>
>>>>>>>> public ArrayList<Vehicle> getVehicles() {
>>>>>>>> return vehicles;
>>>>>>>> }
>>>>>>>>
>>>>>>>> public void setVehicles(ArrayList<Vehicle> vehicles) {
>>>>>>>> this.vehicles = vehicles;
>>>>>>>> }
>>>>>>>> }
>>>>>>>>
>>>>>>>> public class Vehicle {
>>>>>>>> private String name;
>>>>>>>> private Owner owner;
>>>>>>>>
>>>>>>>> public String getName() {
>>>>>>>> return name;
>>>>>>>> }
>>>>>>>>
>>>>>>>> public void setName(String name) {
>>>>>>>> this.name = name;
>>>>>>>> }
>>>>>>>>
>>>>>>>> public Owner getOwner() {
>>>>>>>> return owner;
>>>>>>>> }
>>>>>>>>
>>>>>>>> public void setOwner(Owner owner) {
>>>>>>>> this.owner = owner;
>>>>>>>> }
>>>>>>>> }
>>>>>>>>
>>>>>>>> MappingTool tool = new MappingTool();
>>>>>>>> tool.setInternalContext(new
>>>>>>>> BackwardCompatibilityContext());
>>>>>>>> boolean deep = true;
>>>>>>>> File targetFile = new File("generated-mapping.xml");
>>>>>>>> log.debug("generating mapping file...");
>>>>>>>> tool.addClass(Owner.class, deep);
>>>>>>>> fw = new FileWriter(targetFile);
>>>>>>>> tool.write(fw);
>>>>>>>> log.debug("...done generating mapping file: " +
>>>>>>>> targetFile);
>>>>>>>>
>>>>>>>> But the end result is:
>>>>>>>>
>>>>>>>> <?xml version="1.0" encoding="UTF-8"?>
>>>>>>>> <mapping xmlns="http://castor.exolab.org/"
>>>>>>>> xmlns:cst="http://castor.exolab.org/">
>>>>>>>> <description xmlns="">Castor generated mapping
>>>>>>>> file</description>
>>>>>>>> <class name="tests.Owner">
>>>>>>>> <description xmlns="">Default mapping for class
>>>>>>>> tests.Owner</description>
>>>>>>>> <map-to/>
>>>>>>>> <field name="name" type="java.lang.String">
>>>>>>>> <bind-xml name="name" node="element"/>
>>>>>>>> </field>
>>>>>>>> <field name="vehicles" type="java.lang.Object"
>>>>>>>> collection="arraylist">
>>>>>>>> <bind-xml name="vehicles" node="element"/>
>>>>>>>> </field>
>>>>>>>> </class>
>>>>>>>> </mapping>
>>>>>>>>
>>>>>>>> So it seems it maps Vehicles in the list as Objects, which does not
>>>>>>>> help
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>> --
>>>>>>>
>>>>>>> Syscon Ingenieurbüro für Meß- und Datentechnik GmbH
>>>>>>> Ralf Joachim
>>>>>>> Raiffeisenstraße 11
>>>>>>> 72127 Kusterdingen
>>>>>>> Germany
>>>>>>>
>>>>>>> Tel. +49 7071 3690 52
>>>>>>> Mobil: +49 173 9630135
>>>>>>> Fax +49 7071 3690 98
>>>>>>>
>>>>>>> Internet: www.syscon.eu
>>>>>>> E-Mail: [email protected]
>>>>>>>
>>>>>>> Sitz der Gesellschaft: D-72127 Kusterdingen
>>>>>>> Registereintrag: Amtsgericht Stuttgart, HRB 382295
>>>>>>> Geschäftsleitung: Jens Joachim, Ralf Joachim
>>>>>>>
>>>>>>>
>>>>>>> ---------------------------------------------------------------------
>>>>>>> To unsubscribe from this list, please visit:
>>>>>>>
>>>>>>> http://xircles.codehaus.org/manage_email
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe from this list, please visit:
>>>>>
>>>>> http://xircles.codehaus.org/manage_email
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe from this list, please visit:
>>>
>>> http://xircles.codehaus.org/manage_email
>>>
>>>
>>>
>>>
>>
>>
>
>
--
View this message in context:
http://old.nabble.com/How-to-map-cyclic---recursive-objects--tp26317185p26408424.html
Sent from the Castor - User mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email