<p>Ever get strange memory exceptions with POJO? Even if not, check some issues described below. </p><p>Just spent few hours with debuger to find out, "where is my memory!?" during Birt POJO DataSet usage.</p><p>Little bit theory.</p><p>The provided interface is cute and simple:</p><pre class="_prettyXprint _lang-">public interface IPojoDataSet { open(Object appContext, Map<String, Object> dataSetParamValues); next(); close(); }</pre><p>Actually, Object appContext stands for IRunAndRenderTask.getAppContext(), where I store runtime object, which contains DataSet rows. Does anybody really use DataSet saved in Jar, as it supposed buy Birt POJO functionality developers ? Me not. Have very faint ideas, how it could be done.</p><p>DataSetParamValues is for passing something from report design, I didn't succeed while trying to pass my runtime POJO DataSet object through task.setPararmeter* functions. </p><p> </p><p>This is my solution: </p><pre class="_prettyXprint _lang-">import java.util.Iterator;/** * The Class PojoDataSetContainer. * Wraps any class, that implements Iterable<T> to be passed without great(2-3 times) memory overhead as Birt Pojo DataSet. * Look strange code at org.eclipse.datatools.connectivity.oda.consumer.helper.OdaConnection.open() for reasons to use this class. * There they do toString() , and this often brings you out of memory exception. *
@param <T> * stands for single row type */public class PojoDataSetContainer<T> implements Iterable<T> { /** The iterable. */ private final Iterable<T> iterable; /** * Instantiates a new pojo data set container. * *
@param iterable * the iterable */ public PojoDataSetContainer(Iterable<T> iterable) { this.iterable = iterable; } /** * Iterator. * *
@return the iterator */
@Override public Iterator<T> iterator() { return iterable.iterator(); } /** * To string. * *
@return the string */
@Override public String toString() { return ""; }}</pre><p>And another abstract class, wich helps with POJO: </p><pre class="_prettyXprint _lang-">import java.util.Iterator;import java.util.Map;import org.eclipse.birt.data.oda.pojo.api.IPojoDataSet;/** * The Class AbstractPojoDataSet * *
@param <T> * the generic type. Represents single row of a data. */public abstract class AbstractPojoDataSet<T> implements IPojoDataSet { public static final String CONTEXT_DATASET = "AbstractPojoDataSet.DataSet"; public static final String CONTEXT_REMOVE_FETCHED_ROWS = "AbstractPojoDataSet.RemoveFetchedRows"; /** The rows iterator. */ private Iterator<T> rowsIterator; /** * Open. * *
@param appContext * the Application Context object. Must be Map object.</br> Usually this is IRunAndRenderTask task; task.getAppContext(); map. *
@param dataSetParamValues * the data set param values. Don't know how to use it. */
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override public void open(Object appContext, Map<String, Object> dataSetParamValues) { if (appContext instanceof Map) { Map contextMap = (Map) appContext; if (contextMap.containsKey(CONTEXT_DATASET)) { Object val = contextMap.get(CONTEXT_DATASET); if (val instanceof PojoDataSetContainer<?>) { rowsIterator = ((PojoDataSetContainer<T>) val).iterator(); } else { throw new IllegalArgumentException( "DataSet must be wrapped into PojoDataSetContainer to prevent memory more then twice overhead on toString() conversionsr" + "during org.eclipse.datatools.connectivity.oda.consumer.helper.OdaConnection.open(). "); } } else { throw new IllegalArgumentException("No DataSet information within appContext map! Demanded key is:" + CONTEXT_DATASET); } } else { throw new IllegalArgumentException("Object appContext is not instance of Map! Can't extract setup information!"); } } /** * Next. * *
@return the Dataset row */
@Override public T next() { while (rowsIterator.hasNext()) { return rowsIterator.next(); } return null; } /** * Close. */
@Override public void close() { rowsIterator = null; }}</pre><p>Hope, this could be useful!

</p>