Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Moxy JPA+JAXB mapping issue with list unwrapping(Moxy JPA+JAXB mapping issue with list unwrapping)
Moxy JPA+JAXB mapping issue with list unwrapping [message #938979] Wed, 10 October 2012 06:15 Go to next message
Mark Jones is currently offline Mark Jones
Messages: 5
Registered: October 2012
Junior Member


Hi I am struggling to create a mapping from my JPA object to my targeted xml schema.

My main class structure is as follows for brevity -:

Project {
   private Set<ProjectAbstract> projectAbstracts = new HashSet<ProjectAbstract>(0);
}

ProjectAbstract {

    private String abstract;

    private String fooAttribute;

}


I desire this output.

<project>
<abstract fooAttribute="foo">abstract text</abstract>
<abstract fooAttribute="foo">abstract text</abstract>
</project>


I have tried XMLAdaptor, XmlPath and numerous approaches but I cannot unwrap the set and end up with (or similar) -:

<project>
<ProjectAbstracts>
<abstract fooAttribute="foo">abstract text</abstract>
<abstract fooAttribute="foo">abstract text</abstract>
</ProjectAbstracts>
</project>


I have literally hundreds of classes so creating a full set of JAXB bindings and mapping code really isn't much of an option!

Maybe my XMLadaptor is incorrect but I cant see how to make it accept Collections and work in the way I desire.

Regards

EDIT: I have switched to the latest Moxy to try and achieve this

[Updated on: Wed, 10 October 2012 06:16]

Report message to a moderator

Re: Moxy JPA+JAXB mapping issue with list unwrapping [message #939185 is a reply to message #938979] Wed, 10 October 2012 09:58 Go to previous messageGo to next message
Blaise Doughan is currently offline Blaise Doughan
Messages: 163
Registered: July 2009
Senior Member

Below I'll demonstrate how you can map your use case without an XmlAdapter or any of MOXy's extensions such as @XmlPath.

Project

package forum398114;

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Project {
	
	@XmlElement(name="abstract")
	private Set<ProjectAbstract> projectAbstracts = new HashSet<ProjectAbstract>(0);

}


Project Abstract

package forum398114;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class ProjectAbstract {

    @XmlValue
    private String abstractValue;

    @XmlAttribute
    private String fooAttribute;

}


jaxb.properties

This example will work with any JAXB (JSR-222) implementation. To specify MOXy as your JAXB provider you need to include a file called jaxb.properties in the same package as your domain model with the following entry (see: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html).

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory


Demo

package forum398114;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

	public static void main(String[] args) throws Exception {
		JAXBContext jc = JAXBContext.newInstance(Project.class);
		
		Unmarshaller unmarshaller = jc.createUnmarshaller();
		File xml = new File("src/forum398114/input.xml");
		Project project = (Project) unmarshaller.unmarshal(xml);
		
		Marshaller marshaller = jc.createMarshaller();
		marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
		marshaller.marshal(project, System.out);
	}

}


input.xml/Output

Below is the input to, and output from running the demo code:

<?xml version="1.0" encoding="UTF-8"?>
<project>
   <abstract fooAttribute="foo">abstract text</abstract>
   <abstract fooAttribute="foo">abstract text</abstract>
</project>


For More Information

The following articles provide additional information on the topics used in this post.

- http://blog.bdoughan.com/2011/06/jaxb-and-complex-types-with-simple.html
- http://blog.bdoughan.com/2010/09/jaxb-collection-properties.html
Re: Moxy JPA+JAXB mapping issue with list unwrapping [message #939545 is a reply to message #939185] Wed, 10 October 2012 17:29 Go to previous messageGo to next message
Mark Jones is currently offline Mark Jones
Messages: 5
Registered: October 2012
Junior Member
Thanks very much, it worked exactly as I asked.

Is it possible to take the attribute from a third level class. I am unable to make it work.

Project {
   private Set<ProjectAbstract> projectAbstracts = new HashSet<ProjectAbstract>(0);
}

ProjectAbstract {
    private String abstract;
    private ISO639Lang language;
}

ISO639Lang {
private String ISO639LangCode;
}


I am using this on my package-info.java as I only require a few thousand xml elements within my much larger JPA model.
@XmlAccessorType(XmlAccessType.NONE)


I desire this output.

<project>
<abstract ISO639LangCode="foo">abstract text</abstract>
<abstract ISO639LangCode="foo">abstract text</abstract>
</project>


I could maybe do with some sort of pass through annotation so that the Object is followed but not added to the xml, only its children -:

Or should I use an adaptor? I am trying to avoid this though due to the number of elements I have.

ProjectAbstract {
    private String abstract;
    @XMLEvaluateSubelements
    private ISO639Lang language;
}

ISO639Lang {
@XmlAttribute
private String ISO639LangCode;
}


I particularly appreciate your time as project lead spending time on the forums.

Regards
Re: Moxy JPA+JAXB mapping issue with list unwrapping [message #939573 is a reply to message #939545] Wed, 10 October 2012 18:10 Go to previous messageGo to next message
Mark Jones is currently offline Mark Jones
Messages: 5
Registered: October 2012
Junior Member
Here is my working adaptor example that mixes the attribute and adaptor annotations for the desired effect. However a solution without an adaptor would be great. Thanks.

Quote:


ProjectAbstract {
@XmlValue
private String abstract;
@XmlJavaTypeAdapter(ISO639LangAdaptor.class)
@XmlAttribute(name="cfLangCode")
private ISO639Lang language;
}

ISO639Lang {
@XmlAttribute
private String ISO639LangCode;
}

ISO639LangAdaptor {
public String marshal(ISO639Lang v) throws Exception {
return v.getISO639LangCode();
}
}
Re: Moxy JPA+JAXB mapping issue with list unwrapping [message #940289 is a reply to message #938979] Thu, 11 October 2012 09:56 Go to previous messageGo to next message
Blaise Doughan is currently offline Blaise Doughan
Messages: 163
Registered: July 2009
Senior Member

The good news is that this can be done without the use of an XmlAdapter. I'll demonstrate below with an example.

Project

package forum398114;

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Project {
	
	@XmlElement(name="abstract")
	private Set<ProjectAbstract> projectAbstracts = new HashSet<ProjectAbstract>(0);

}


ProjectAbstract

We will map the field/property of type ISO639Lang as an @XmlAttribute. We can do this if that class has one mapping of type @XmlValue.

package forum398114;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class ProjectAbstract {

	@XmlValue
    private String abstractValue;

	@XmlAttribute(name="ISO639LangCode")
    private ISO639Lang language;

}


ISO639Lang

This class has one mapping of type @XmlValue.

package forum398114;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class ISO639Lang {
	
	@XmlValue
	private String ISO639LangCode;

}


Demo

package forum398114;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

	public static void main(String[] args) throws Exception {
		JAXBContext jc = JAXBContext.newInstance(Project.class);
		
		Unmarshaller unmarshaller = jc.createUnmarshaller();
		File xml = new File("src/forum398114/input.xml");
		Project project = (Project) unmarshaller.unmarshal(xml);
		
		Marshaller marshaller = jc.createMarshaller();
		marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
		marshaller.marshal(project, System.out);
	}

}


input.xml/Output

<?xml version="1.0" encoding="UTF-8"?>
<project>
   <abstract ISO639LangCode="foo">abstract text</abstract>
   <abstract ISO639LangCode="foo">abstract text</abstract>
</project>
Re: Moxy JPA+JAXB mapping issue with list unwrapping [message #940593 is a reply to message #940289] Thu, 11 October 2012 15:50 Go to previous message
Mark Jones is currently offline Mark Jones
Messages: 5
Registered: October 2012
Junior Member
Hi thanks again. This worked on the test case but failed on my code.

Some sleuthing revealed this was down to JPA bytecode manipulation as I am using lazy fetching and the OSIV pattern for this read only part of the code. So far even during fairly complex documents the only error point was at -:

@XmlValue private String ISO639LangCode;

As have hundreds of entities and countless thousands of JPA fields so I am trying to keep the annotations to a minimum otherwise I will be chasing small xml output bugs for the rest of my life.

Is there some way around this?

Could JPA or JAXB be forced into a different mode for example?

Regards

EDIT: I have solved this annotating on the property works.

Thanks again.

[Updated on: Thu, 11 October 2012 16:24]

Report message to a moderator

Previous Topic:maven repo problem
Next Topic:Memory leak issue
Goto Forum:
  


Current Time: Fri Aug 01 22:35:29 EDT 2014

Powered by FUDForum. Page generated in 0.01577 seconds