0

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?

marcolopes
  • 9,232
  • 14
  • 54
  • 65

1 Answers1

0

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...

marcolopes
  • 9,232
  • 14
  • 54
  • 65