Hello, I have a question about unmarshaling a query result into JAXB
object(s). My database collection contains documents that all contain the
same type of root element, let's call it Element1.
Originally I was doing something like this (I know it's silly but it worked
just fine for small data sets):
String CLOSING_TAG = "</Element1>";
Context context = ...
Unmarshaller um = ...
String predicate1 = ...
String predicate2 = ...
String query = "//Element1[" + predicate1 + " and " + predicate2 + "]";
String result = new XQuery(query).execute(context);
if (result != null && !result.isEmpty()) {
ArrayList<Element1> elements = new ArrayList<>();
int index = -1;
int beginIndex = 0;
while ((index = result.indexOf(CLOSING_TAG, beginIndex)) != -1) {
int endIndex = index + CLOSING_TAG.length();
String element1 = result.substring(beginIndex, endIndex);
beginIndex = endIndex + 1;
elements.add(((Element1) um.unmarshal(new
ByteArrayInputStream(element1.getBytes()))));
}
// do something with the elements
}
But when I got into larger data sets (my DB collection is currently approx.
1GB total size and has just over 20k documents) this started to fail
apparently due to trying to convert the entire result to a string at one
time (out of memory error, despite setting -Xmx16384m). So I dig through
the examples to find a better way and changed my code to this:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Iter iter = null;
Serializer ser = null;
QueryProcessor proc = new QueryProcessor(query, context);
iter = proc.iter();
ser = proc.getSerializer(baos);
proc.close();
if (iter != null && ser != null) {
ArrayList<Element1> elements = new ArrayList<>();
for(Item item; (item = iter.next()) != null;) {
baos.reset();
ser.serialize(item);
elements.add(((Element1) um.unmarshal(new
ByteArrayInputStream(baos.toByteArray()))));
}
ser.close();
// do something with the elements
}
This appears to work fine but I am just wondering if there is a
better/faster way to do it? At first glance, serializing to a
ByteArrayOutputSream only to then turn around and use a
ByteArrayInputStream to unmarshal with JAXB seems wasteful.
Thanks for taking the time to read,
Zach