Index: src/org/eclipse/persistence/internal/oxm/TreeObjectBuilder.java =================================================================== --- src/org/eclipse/persistence/internal/oxm/TreeObjectBuilder.java (revision 5576) +++ src/org/eclipse/persistence/internal/oxm/TreeObjectBuilder.java (working copy) @@ -81,7 +81,7 @@ } public void addTransformationMapping(AbstractTransformationMapping transformationMapping) { - if (null == getTransformationMappings()) { + if (null == this.transformationMappings) { this.transformationMappings = new ArrayList(); } transformationMappings.add(transformationMapping); @@ -96,7 +96,7 @@ } public void addContainerValue(ContainerValue containerValue) { - if (null == getContainerValues()) { + if (null == this.containerValues) { this.containerValues = new ArrayList(); } this.containerValues.add(containerValue); @@ -107,7 +107,7 @@ } public void addNullCapableValue(NullCapableValue nullCapableValue) { - if (null == getNullCapableValues()) { + if (null == this.nullCapableValues) { this.nullCapableValues = new ArrayList(); } this.nullCapableValues.add(nullCapableValue); @@ -172,7 +172,18 @@ mappingNodeValue = new XMLFragmentCollectionMappingNodeValue((XMLFragmentCollectionMapping)xmlMapping); } else if (xmlMapping instanceof XMLCollectionReferenceMapping) { XMLCollectionReferenceMapping xmlColMapping = (XMLCollectionReferenceMapping)xmlMapping; - Iterator fieldIt = xmlColMapping.getFields().iterator(); + List fields = xmlColMapping.getFields(); + XMLField xmlColMappingField = (XMLField) xmlColMapping.getField(); + XPathNode branchNode; + if(null == xmlColMappingField) { + if(fields.size() > 1) { + addChild(XPathFragment.SELF_FRAGMENT, new XMLCollectionReferenceMappingMarshalNodeValue(xmlColMapping), xmlDescriptor.getNamespaceResolver()); + } + branchNode = rootXPathNode; + } else { + branchNode = addChild(((XMLField) xmlColMapping.getField()).getXPathFragment(), new XMLCollectionReferenceMappingMarshalNodeValue(xmlColMapping), xmlDescriptor.getNamespaceResolver()); + } + Iterator fieldIt = fields.iterator(); while (fieldIt.hasNext()) { XMLField xmlFld = (XMLField)fieldIt.next(); mappingNodeValue = new XMLCollectionReferenceMappingNodeValue(xmlColMapping, xmlFld); @@ -182,7 +193,7 @@ if (mappingNodeValue.isNullCapableValue()) { addNullCapableValue((NullCapableValue)mappingNodeValue); } - addChild(xmlFld.getXPathFragment(), mappingNodeValue, xmlDescriptor.getNamespaceResolver()); + branchNode.addChild(xmlFld.getXPathFragment(), mappingNodeValue, xmlDescriptor.getNamespaceResolver()); } continue; } else if (xmlMapping instanceof XMLObjectReferenceMapping) { @@ -283,8 +294,8 @@ } } - public void addChild(XPathFragment xPathFragment, NodeValue nodeValue, NamespaceResolver namespaceResolver) { - getRootXPathNode().addChild(xPathFragment, nodeValue, namespaceResolver); + public XPathNode addChild(XPathFragment xPathFragment, NodeValue nodeValue, NamespaceResolver namespaceResolver) { + return getRootXPathNode().addChild(xPathFragment, nodeValue, namespaceResolver); } public AbstractRecord buildRow(AbstractRecord record, Object object, org.eclipse.persistence.internal.sessions.AbstractSession session) { @@ -315,11 +326,10 @@ boolean hasValue = false; NamespaceResolver namespaceResolver = ((XMLDescriptor)this.getDescriptor()).getNamespaceResolver(); - List attributeChildren = rootXPathNode.getAttributeChildren(); + List attributeChildren = rootXPathNode.getAttributeChildren(); if (null != attributeChildren) { for (int x = 0, attributeChildrenSize=attributeChildren.size(); x < attributeChildrenSize; x++) { - XPathNode attributeNode = (XPathNode)rootXPathNode.getAttributeChildren().get(x); - hasValue = attributeNode.marshal(marshalRecord, object, session, namespaceResolver, null, ObjectMarshalContext.getInstance()) || hasValue; + hasValue = attributeChildren.get(x).marshal(marshalRecord, object, session, namespaceResolver, null, ObjectMarshalContext.getInstance()) || hasValue; } } @@ -327,11 +337,10 @@ hasValue = rootXPathNode.getAnyAttributeNode().marshal(marshalRecord, object, session, namespaceResolver, null, ObjectMarshalContext.getInstance()) || hasValue; } - List selfChildren = rootXPathNode.getSelfChildren(); + List selfChildren = rootXPathNode.getSelfChildren(); if (null != selfChildren) { for (int x = 0, selfChildrenSize=selfChildren.size(); x < selfChildrenSize; x++) { - XPathNode childNode = (XPathNode)selfChildren.get(x); - childNode.marshalSelfAttributes(marshalRecord, object, session, namespaceResolver, marshalRecord.getMarshaller()); + selfChildren.get(x).marshalSelfAttributes(marshalRecord, object, session, namespaceResolver, marshalRecord.getMarshaller()); } } @@ -375,5 +384,5 @@ public AbstractRecord createRecord(int size, AbstractSession session) { return createRecord(session); } - -} + +} \ No newline at end of file Index: src/org/eclipse/persistence/internal/oxm/XMLCollectionReferenceMappingMarshalNodeValue.java =================================================================== --- src/org/eclipse/persistence/internal/oxm/XMLCollectionReferenceMappingMarshalNodeValue.java (revision 0) +++ src/org/eclipse/persistence/internal/oxm/XMLCollectionReferenceMappingMarshalNodeValue.java (revision 0) @@ -0,0 +1,160 @@ +package org.eclipse.persistence.internal.oxm; + +import java.util.List; +import javax.xml.namespace.QName; + +import org.eclipse.persistence.internal.oxm.record.MarshalContext; +import org.eclipse.persistence.internal.oxm.record.ObjectMarshalContext; +import org.eclipse.persistence.internal.queries.ContainerPolicy; +import org.eclipse.persistence.internal.sessions.AbstractSession; +import org.eclipse.persistence.oxm.NamespaceResolver; +import org.eclipse.persistence.oxm.XMLDescriptor; +import org.eclipse.persistence.oxm.XMLField; +import org.eclipse.persistence.oxm.mappings.XMLCollectionReferenceMapping; +import org.eclipse.persistence.oxm.record.MarshalRecord; + +public class XMLCollectionReferenceMappingMarshalNodeValue extends MappingNodeValue implements ContainerValue { + + private XMLCollectionReferenceMapping xmlCollectionReferenceMapping; + private XPathNode branchNode; + + public XMLCollectionReferenceMappingMarshalNodeValue(XMLCollectionReferenceMapping xmlCollectionReferenceMapping) { + this.xmlCollectionReferenceMapping = xmlCollectionReferenceMapping; + branchNode = new XPathNode(); + NamespaceResolver namespaceResolver = ((XMLDescriptor) xmlCollectionReferenceMapping.getDescriptor()).getNamespaceResolver(); + List fkFields = xmlCollectionReferenceMapping.getFields(); + for(int x=0, fkFieldsSize=fkFields.size(); x getAttributeChildren() { return this.attributeChildren; } - public List getNonAttributeChildren() { + public List getNonAttributeChildren() { return this.nonAttributeChildren; } - public List getSelfChildren() { + public List getSelfChildren() { return this.selfChildren; } @@ -183,7 +183,7 @@ } } - public void addChild(XPathFragment anXPathFragment, NodeValue aNodeValue, NamespaceResolver namespaceResolver) { + public XPathNode addChild(XPathFragment anXPathFragment, NodeValue aNodeValue, NamespaceResolver namespaceResolver) { if (null != anXPathFragment && anXPathFragment.nameIsText()) { if (aNodeValue.isOwningNode(anXPathFragment)) { XPathNode textXPathNode = new XPathNode(); @@ -200,7 +200,7 @@ nonAttributeChildren = new ArrayList(); } nonAttributeChildren.add(textXPathNode); - return; + return textXPathNode; } } @@ -255,7 +255,7 @@ } setAnyNode(xPathNode); } - return; + return xPathNode; } boolean isSelfFragment = XPathFragment.SELF_FRAGMENT.equals(anXPathFragment); @@ -289,6 +289,7 @@ XPathFragment nextFragment = anXPathFragment.getNextFragment(); xPathNode.addChild(nextFragment, aNodeValue, namespaceResolver); } + return xPathNode; } public boolean marshal(MarshalRecord marshalRecord, Object object, AbstractSession session, NamespaceResolver namespaceResolver, XMLMarshaller marshaller, MarshalContext marshalContext) { Index: src/org/eclipse/persistence/oxm/mappings/XMLCollectionReferenceMapping.java =================================================================== --- src/org/eclipse/persistence/oxm/mappings/XMLCollectionReferenceMapping.java (revision 5576) +++ src/org/eclipse/persistence/oxm/mappings/XMLCollectionReferenceMapping.java (working copy) @@ -24,6 +24,7 @@ import org.eclipse.persistence.exceptions.DatabaseException; import org.eclipse.persistence.exceptions.DescriptorException; import org.eclipse.persistence.internal.descriptors.ObjectBuilder; +import org.eclipse.persistence.internal.helper.DatabaseField; import org.eclipse.persistence.internal.helper.NonSynchronizedVector; import org.eclipse.persistence.internal.oxm.Reference; import org.eclipse.persistence.internal.oxm.ReferenceResolver; @@ -62,6 +63,7 @@ public class XMLCollectionReferenceMapping extends XMLObjectReferenceMapping implements ContainerMapping { protected ContainerPolicy containerPolicy; // type of container used to hold the aggregate objects private static final String SPACE = " "; + private DatabaseField field; private boolean usesSingleNode; private boolean reuseContainer; @@ -77,6 +79,31 @@ this.usesSingleNode = false; } + public DatabaseField getField() { + return field; + } + + public void setField(DatabaseField field) { + this.field = field; + } + + + /** + * Get the XPath String + * @return String the XPath String associated with this Mapping + */ + public String getXPath() { + return getField().getName(); + } + + /** + * Set the Mapping field name attribute to the given XPath String + * @param xpathString String + */ + public void setXPath(String xpathString) { + this.setField(new XMLField(xpathString)); + } + /** * INTERNAL: * Retrieve the target object's primary key value that is mapped to a given @@ -166,6 +193,9 @@ */ public void initialize(AbstractSession session) throws DescriptorException { super.initialize(session); + if(null != getField()) { + setField(getDescriptor().buildField(getField())); + } ContainerPolicy cp = getContainerPolicy(); if (cp != null) { if (cp.getContainerClass() == null) {