Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » MOXy - How to map multiple nodes with the same path?
MOXy - How to map multiple nodes with the same path? [message #487853] Thu, 24 September 2009 15:08 Go to next message
Matti Hansson is currently offline Matti HanssonFriend
Messages: 68
Registered: July 2009
Member
Hi!
I have a value which I map to two fields:
MyClass {                     <MyXML>
   value;        <-->            <valuePartA>ABC</valuePartA>
}                                <valuePartB>123</valuePartB>
                              </MyXML>

Using a transformation mapping, this is no problem. The trouble comes from the fact that the node <valuePartB> may appear many times in <MyXML>, and I need all "B-values" to create the value in MyClass.

Is this at all possible? Maybe by having an intermediary class with a "valueA" and a list of "valueB"s, but how would the transformer get hold of the intermediary instance?
Thanks!

[Updated on: Thu, 24 September 2009 15:21]

Report message to a moderator

Re: MOXy - How to map multiple nodes with the same path? [message #488885 is a reply to message #487853] Wed, 30 September 2009 15:33 Go to previous messageGo to next message
Blaise Doughan is currently offline Blaise DoughanFriend
Messages: 163
Registered: July 2009
Senior Member

Hello Matti,

For situations like this I recommend using a converter instead of a transformation mapping. With this approach you use an intermediate object as you describe.

I am assuming your domain object looks something like the following:

public class MyObject {
    private String[] value;
    ...
}


An intermediate object could be created that looks like:

public class IntermediateValue {
    private String partA;
    private List<String> partB;
    ...


When mapping the value property on MyObject I would use an XMLCompositeObjectMapping, setting the reference class to be IntermediateValue.class (instead of the actual type of the value property).

XMLCompositeObjectMapping valueMapping = new XMLCompositeObjectMapping();
valueMapping.setReferenceClass(IntermediateValue.class);
valueMapping.setAttributeName("value");
valueMapping.setXPath("value");
valueMapping.setConverter(new ValueConverter());
xmlDescriptor.addMapping(valueMapping);


The ValueConvter class would look something like the following:

import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.sessions.Session;

public class ValueConverter implements Converter {

    public void initialize(DatabaseMapping mapping, Session session) {
    }

    public Object convertObjectValueToDataValue(Object objectValue, Session session) {
        String[] stringArray = (String[]) objectValue;
        IntermediateValue intermediateValue = new IntermediateValue();
        intermediateValue.setPartA(stringArray[0]);
        for(int x=1; x<stringArray.length; x++) {
            intermediateValue.getPartB().add(stringArray[x]);
        }
        return intermediateValue;
    }

    public Object convertDataValueToObjectValue(Object dataValue, Session session) {
        IntermediateValue intermediateValue = (IntermediateValue) dataValue;
        String[] stringArray = new String[intermediateValue.getPartB().size() + 1];
        stringArray[0] = intermediateValue.getPartA();
        for(int x=0; x<intermediateValue.getPartB().size(); x++) {
            stringArray[x + 1] = intermediateValue.getPartB().get(x);
        }
        return stringArray;
    }

    public boolean isMutable() {
        return true;
    }

}


This would allow you to produce XML that looks like the following:

<MyXML>
   <value>
      <valuePartA>ABC</valuePartA>
      <valuePartB>123</valuePartB>
      <valuePartB>456</valuePartB>
   </value>
</MyXML>


If you want to eliminate the "value" node then the XPath on the XMLCompositeObjectMapping should be changed to "." instead of "value". It appears as though there is a bug in EclipesLink 1.2 where conveters are not called on XMLCompositeObjectMappings when the XPath is ".". This bug has been fixed in the EclipseLink 2.0 stream.

-Blaise

[Updated on: Fri, 16 October 2009 20:52]

Report message to a moderator

Re: MOXy - How to map multiple nodes with the same path? [message #488938 is a reply to message #488885] Wed, 30 September 2009 18:56 Go to previous messageGo to next message
Matti Hansson is currently offline Matti HanssonFriend
Messages: 68
Registered: July 2009
Member
Thank you so much for your help, Blaise!
And to repay you: a bug report Razz

My case got a little more complicated, so I decided to use an XMLChoiceObjectMapping for the value instead. Going from XML to Java proved to be a cinch but when going the other way the converter never ran.

I did some debugging, and it seems like the mapping is looking for which XMLField is associated with the object, but it doesn't take into account that the object might have to be converted back first, so no XMLField is found and nothing is written.

I understand the object may be converted to any class, so it's impossible to tell which converter to use until it's been converted. Because of this catch 22 the behaviour might not be a bug, in which case I apologize.

I managed to solve my problem with an XMLAnyObjectMapping, so it doesn't bother me.

Anyway, thanks again!
/Matti
Re: MOXy - How to map multiple nodes with the same path? [message #491977 is a reply to message #487853] Fri, 16 October 2009 20:49 Go to previous message
Blaise Doughan is currently offline Blaise DoughanFriend
Messages: 163
Registered: July 2009
Senior Member

Update

The bug about converters and self mappings has been fixed in the EclipseLink 2.0 stream.

-Blaise
Previous Topic:Mapping arrays
Next Topic:Using generic and specific relationships
Goto Forum:
  


Current Time: Fri Apr 19 14:31:46 GMT 2024

Powered by FUDForum. Page generated in 0.01841 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top