I have a specific query method in all my managers that must return a transient collection, but i want to CLOSE the query immediately after executing it.
tx.begin();
Query query=pm.newQuery(...);
Collection col=(Collection)query.execute();
pm.makeTransientAll(col,true);
query.close();
tx.commit();
The problem: The collection CANNOT be accessed after the query is closed (DN knows the identity?) otherwise it throws a "Query has been closed" error!
The solution: Create a COPY of the original collection!
Collection col=new ArrayList((Collection)query.execute());
But i want to avoid that... Even if it's a local copy and it's not a deep clone, it still allocates the space needed for the entire array of elements (so, at some point there is going to be 2x allocated memory) and i would like to avoid that.
I'm i missing something? Is there a way to avoid the creation of a clone?
Well, i found the reason of this behavior:
The query Object returned (collection) if an instance of: org.datanucleus.store.rdbms.query.ForwardQueryResult
that extends: AbstractRDBMSQueryResult
that extends: AbstractQueryResult
that extends: AbstractList
so, i get an object that is a LIST implementation, and the query result is bound to that implementation.
/** The Result Objects. */
protected List resultObjs = new ArrayList();
/**
* Method to return the results as an array.
* @return The array.
*/
public synchronized Object[] toArray()
{
assertIsOpen();
advanceToEndOfResultSet();
return resultObjs.toArray();
}
So, i cannot avoid the creation of a NEW array...