views:

74

answers:

2

I've got a fairly simple, but potentially large structure to serialize. Basically the structure of the XML will be:

<simple_wrapper>
   <main_object_type>
     <sub_objects>
   </main_object_type>
     ... main_object_type repeats up to 5,000 times
</simple_wrapper>

The main_object_type can have a significant amount of data. On my first 3,500 record extract, I had to give the JVM way more memory than it should need.

So, I'd like to write out to disk after each (or a bunch of) main_object_type.

I know that setting Marshaller.JAXB_FRAGMENT would allow it fragments, but I loose the outer xml document tags and the <simple_wrapper>.

Any suggestions?

A: 

You can marshal your object into a SAX or StAX stream.

lexicore
If I use a stream, won't the standard method of creating a `JAXBElement<?>` for the `<simple_wrapper>` still require all the contained objects to be held in memory? What I'm looking for is how to break it up without having to incur a lot of manual work with writing the `<xml>` headers, etc. I want to open the `<simple_wrapper>` and write each `<main_object_type>` as they are retrieved from the DB, without too much monkey work.
Intellectual Tortoise
Try using @XmlID with a custom IDResolver:http://weblogs.java.net/blog/2005/08/15/pluggable-ididref-handling-jaxb-20Your simple wrapper will only store the ids of objects and retrieve object instances via the id resolver.
lexicore
A: 

How about the following?

JAXBContext jaxbContext= JAXBContext.newInstance(MainObjectType.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);

OutputStreamWriter writer = new OutputStreamWriter(System.out);

// Manually open the root element
writer.write("<simple_wrapper>");

// Marshal the objects out individually
marshaller.marshal(mainObjectType1, writer);
marshaller.marshal(mainObjectType2, writer);
marshaller.marshal(mainObjectType3, writer);
marshaller.marshal(mainObjectType4, writer);
...

// Manually close the root element
writer.write("</simple_wrapper>");
writer.close();

This assumes you have an @XmlRootElement on MainObjectType

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class MainObjectType {
    ...
}
Blaise Doughan