Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] [MOXy] Open tags in wrong order when using XMLChoiceCollectionMapping and class hierarchy

Hi Polly,

I don't see anything wrong with how your mapping is defined. Looks like a bug with ChoiceCollectionMapping and GroupingElements in the XPath. If you want to open a bug on this, I'll take a look at it. From a quick look at the code, it looks like we may not be calling openStartGroupingElements() on the MarshalRecord before we start marshalling out the values which could cause this kind of behaviour.

I'll need to debug it to be sure though.

-Matt

polly.c.chang wrote:

Hi,

I am seeing some weird behavior with both EclipseLink 1.0.2 and 1.1.  I have
an object called Container that has a List of Properties.  Property is
actually an abstract super class.  The subclasses that may be stored in the
Container's list are Noun, Element, and Attribute.  The XML looks like:

<Container xmlns="http://www.foo.com/bar/2";>
  <Properties>
     <Noun nounName="Metadata1" />
     <Element nounName="Metadata2" maxOccurs="1" />
     <Element nounName="Metadata3" maxOccurs="1" />
     <Attribute nounName="Metadata4" />
  </Properties>
</Container>

I am specifying this list using an XMLChoiceCollectionMapping.  The xpaths
are "Properties/Noun", "Properties/Element", and "Properties/Attribute". Unmarshalling works fine, but marshalling gives me a very strange result. Instead of getting back the same XML as above, I get:

<Container xmlns="http://www.foo.com/bar/2";>
  <Noun>
     <Properties nounName="Metadata1" />
     <Element nounName="Metadata2" maxOccurs="1" />
     <Element nounName="Metadata3" maxOccurs="1" />
     <Attribute nounName="Metadata4" />
  </Properties>
</Container>

Notice that the Noun and Properties open tags are flipped!  This is invalid
XML.  I debugged into the EclipseLink code and found that the problem occurs
in XMLChoiceCollectionMappingMarshalNodeValue.  The code snippet is:

  	if(associatedNodeValue != null) {
   		//Find the correct fragment
   		XPathFragment frag = associatedField.getXPathFragment();
   		while(frag != null) {
   			if(associatedNodeValue.isOwningNode(frag)) {
   				ContainerValue nestedNodeValue =
(ContainerValue)((XMLChoiceCollectionMappingUnmarshalNodeValue)associatedNodeValue).getChoiceElementNodeValue();
   				nestedNodeValue.marshalSingleValue(frag, marshalRecord, object,
fieldValue, session, namespaceResolver, marshalContext);
   				break;
   			}
               frag = frag.getNextFragment();
               //if next frag is null, call node value before the loop
breaks
               if(frag == null) {
                   ContainerValue nestedNodeValue =
(ContainerValue)((XMLChoiceCollectionMappingUnmarshalNodeValue)associatedNodeValue).getChoiceElementNodeValue();
                   nestedNodeValue.marshalSingleValue(frag, marshalRecord,
object, fieldValue, session, namespaceResolver, marshalContext);
               }
           }
       }
The problem is that for some reason, isOwningNode returns false for
"Properties" when evaluating "Properties/Noun".  All the other xpaths
evaluate correctly.

I looked in the deployment descriptor mapping but it looks correct to me. This leads me to think that what I'm seeing is a bug in EclipseLink. Do you
see something that I'm specifying incorrectly?

<class-mapping-descriptor xsi:type="xml-class-mapping-descriptor"> <class>com.foo.model.Container</class> <alias>Container</alias> <events xsi:type="event-policy"/> <querying xsi:type="query-policy"/> <attribute-mappings> <attribute-mapping xsi:type="xml-choice-collection-mapping"> <attribute-name>properties</attribute-name> <container-policy xsi:type="list-container-policy"> <collection-type>java.util.ArrayList</collection-type> </container-policy> <field-to-class-association> <xml-field name="Properties/Noun" xsi:type="node"/> <class-name>com.foo.model.Noun</class-name> </field-to-class-association> <field-to-class-association> <xml-field name="Properties/Element" xsi:type="node"/> <class-name>com.foo.model.Element</class-name> </field-to-class-association> <field-to-class-association> <xml-field name="Properties/Attribute" xsi:type="node"/> <class-name>com.foo.model.Attribute</class-name> </field-to-class-association> </attribute-mapping> </attribute-mappings> <descriptor-type>aggregate</descriptor-type> <instantiation/> <copying xsi:type="instantiation-copy-policy"/> <default-root-element>Container</default-root-element> <default-root-element-field name="Container" xsi:type="node"> <leaf-element-type>{http://www.foo.com/bar/2}ContainerType</leaf-element-type> </default-root-element-field> <namespace-resolver> <namespaces/> <default-namespace-uri>http://www.foo.com/bar/2</default-namespace-uri> </namespace-resolver> <schema xsi:type="schema-file-reference"> <schema-context>/ContainerType</schema-context> <node-type>complex-type</node-type> </schema> </class-mapping-descriptor> <class-mapping-descriptor xsi:type="xml-class-mapping-descriptor"> <class>com.foo.model.Property</class> <alias>Property</alias> <inheritance xsi:type="qname-inheritance-policy"> <class-indicator-field name="@dummy" xsi:type="node"/> <class-indicator-mappings> <class-indicator-mapping> <class>com.foo.model.Noun</class> <class-indicator xsi:type="xsd:string">NounType</class-indicator> </class-indicator-mapping> <class-indicator-mapping> <class>com.foo.model.Element</class> <class-indicator xsi:type="xsd:string">ElementType</class-indicator> </class-indicator-mapping> <class-indicator-mapping> <class>com.foo.model.Attribute</class> <class-indicator xsi:type="xsd:string">AttributeType</class-indicator> </class-indicator-mapping> </class-indicator-mappings> </inheritance> <events xsi:type="event-policy"/> <querying xsi:type="query-policy"/> <attribute-mappings> <attribute-mapping xsi:type="xml-direct-mapping"> <attribute-name>nounName</attribute-name> <field name="@nounName" xsi:type="node"/> </attribute-mapping> </attribute-mappings> <descriptor-type>aggregate</descriptor-type> <instantiation/> <copying xsi:type="instantiation-copy-policy"/> <namespace-resolver> <namespaces/> <default-namespace-uri>http://www.foo.com/bar/2</default-namespace-uri> </namespace-resolver> <schema xsi:type="schema-file-reference"> <schema-context>/PropertyType</schema-context> <node-type>complex-type</node-type> </schema> </class-mapping-descriptor> <class-mapping-descriptor xsi:type="xml-class-mapping-descriptor"> <class>com.foo.model.Noun</class> <alias>Noun</alias> <inheritance xsi:type="qname-inheritance-policy"> <parent-class>com.foo.model.Property</parent-class> </inheritance> <events xsi:type="event-policy"/> <querying xsi:type="query-policy"/> <descriptor-type>aggregate</descriptor-type> <instantiation/> <copying xsi:type="instantiation-copy-policy"/> <namespace-resolver> <namespaces/> <default-namespace-uri>http://www.foo.com/bar/2</default-namespace-uri> </namespace-resolver> <schema xsi:type="schema-file-reference"> <schema-context>/NounType</schema-context> <node-type>complex-type</node-type> </schema> </class-mapping-descriptor> <class-mapping-descriptor xsi:type="xml-class-mapping-descriptor"> <class>com.foo.model.Element</class> <alias>Element</alias> <inheritance xsi:type="qname-inheritance-policy"> <parent-class>com.foo.model.Property</parent-class> </inheritance> <events xsi:type="event-policy"/> <querying xsi:type="query-policy"/> <attribute-mappings> <attribute-mapping xsi:type="xml-direct-mapping"> <attribute-name>maxOccurs</attribute-name> <field name="@maxOccurs" xsi:type="node"/> </attribute-mapping> </attribute-mappings> <descriptor-type>aggregate</descriptor-type> <instantiation/> <copying xsi:type="instantiation-copy-policy"/> <namespace-resolver> <namespaces/> <default-namespace-uri>http://www.foo.com/bar/2</default-namespace-uri> </namespace-resolver> <schema xsi:type="schema-file-reference"> <schema-context>/ElementType</schema-context> <node-type>complex-type</node-type> </schema> </class-mapping-descriptor> <class-mapping-descriptor xsi:type="xml-class-mapping-descriptor"> <class>com.foo.model.Attribute</class> <alias>Attribute</alias> <inheritance xsi:type="qname-inheritance-policy"> <parent-class>com.foo.model.Property</parent-class> </inheritance> <events xsi:type="event-policy"/> <querying xsi:type="query-policy"/> <descriptor-type>aggregate</descriptor-type> <instantiation/> <copying xsi:type="instantiation-copy-policy"/> <namespace-resolver> <namespaces/> <default-namespace-uri>http://www.foo.com/bar/2</default-namespace-uri> </namespace-resolver> <schema xsi:type="schema-file-reference"> <schema-context>/AttributeType</schema-context> <node-type>complex-type</node-type> </schema> </class-mapping-descriptor>
Thanks!
--Polly


Back to the top