.....
objColl = (Collection) q.execute();
returnColl.addAll(objColl);
q.close(objColl);
tx.commit(); //commit, xact boundary ends here
}finally
{
//make sure to rollback the transaction if still active
if(tx.isActive())
tx.rollback();
}
//pm_.close();
return returnColl;
In the code above, if I comment out pm_.close() I get a warning here:
WARN [com.triactive.jdo.PersistenceManagerImpl] Forcibly closing com.triactive.jdo.PersistenceManagerImpl
com.triactive.jdo.PersistenceManagerNotClosedException: The PersistenceManager allocated at this point was never closed.
If I uncomment the line above, I get the following error:
javax.jdo.JDOFatalUserException: Persistence manager has been closed
Any way I can avoid the warning and the error?
Note that this warning was never occuring with MySQL; I only discovered the warning with SQL Server 2005
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I tried placing the pm_close() line at the end of the finally branch and it made no difference. I still get the javax.jdo.JDOFatalUserException: Persistence manager has been closed ERROR.
I even tried placing the pm_.close() inside an if statement that only closes the persistence manager if it's not already closed. The log indicated that the if block is entered indicating that the persistence manager is not yet closed; yet when I try to close the persistence manager, I get the ERROR above.
Any suggestions?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Your method returns persistent objects to its caller, who presumably uses them.
You can't use persistent objects whose PersistenceManager has been closed.
The lifetime of the PM either has to span over all the code that will use the
persistent objects, or your query method needs to return objects which are
not persistent. There are typically two ways of handling the latter:
1. Use "value object" classes, and return value objects instead of persistent
objects.
2. Make sure the persistent objects are fully loaded into memory
(pm.retrieve()) and then transition them to transient (pm.makeTransient()).
Then they're no longer persistent and no longer tied to a PM. Note that if
you do this the objects lose their JDO identity.
In JDO 2.0 they've introduced methods to "detach" objects from a PM and later
"reattach" them to a different one. It works much like makeTransient() except
the objects don't lose their identity.
I very much want to upgrade TJDO to support JDO 2.0, but it's been hard to find
the time. I have added most of the new JDO 2.0 Query features though.
HTH,
Mike
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I very much appreciate your help over the past few weeks!
If I'm understanding you correctly, the returnColl object that is returned at the end of the method is a persistent object. One of your suggestions is to make returnColl a non persistent object.
Regarding pm.retrieve and pm.transient, am I use to these methods to load returnColl completely into memory and then transition it to transient, and finally pass it back at the end of the method.
Could you confirm the above, and provide an example. That would be great.
Thanks...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Could you expand on what you meant by "objects losing their JDO identity" above if one uses retrieve/makeTransient way. I tried the method above but I'm getting a null pointer exception in my JSP code where I access the object returned.
Thanks..
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm posting my new get() method here. As suggested, I used the retrieve and transient method calls before copying over the objects to returnColl. Nonetheless, I'm still getting a null pointer exception. Any ideas?
Hi,
I'm posting from my get() method below.
this.pm_ = pmf.getPersistenceManager();
Collection objColl = null;
Collection returnColl = new ArrayList();
Transaction tx = pm_.currentTransaction();
Query q = null;
try{
tx.begin(); //xact boundary begins here
.....
objColl = (Collection) q.execute();
returnColl.addAll(objColl);
q.close(objColl);
tx.commit(); //commit, xact boundary ends here
}finally
{
//make sure to rollback the transaction if still active
if(tx.isActive())
tx.rollback();
}
//pm_.close();
return returnColl;
In the code above, if I comment out pm_.close() I get a warning here:
WARN [com.triactive.jdo.PersistenceManagerImpl] Forcibly closing com.triactive.jdo.PersistenceManagerImpl
com.triactive.jdo.PersistenceManagerNotClosedException: The PersistenceManager allocated at this point was never closed.
If I uncomment the line above, I get the following error:
javax.jdo.JDOFatalUserException: Persistence manager has been closed
Any way I can avoid the warning and the error?
Note that this warning was never occuring with MySQL; I only discovered the warning with SQL Server 2005
Hi,
I would place the pm_.close() line at the end of the finally branch.
Best regards
Heiko
I tried placing the pm_close() line at the end of the finally branch and it made no difference. I still get the javax.jdo.JDOFatalUserException: Persistence manager has been closed ERROR.
I even tried placing the pm_.close() inside an if statement that only closes the persistence manager if it's not already closed. The log indicated that the if block is entered indicating that the persistence manager is not yet closed; yet when I try to close the persistence manager, I get the ERROR above.
Any suggestions?
Your method returns persistent objects to its caller, who presumably uses them.
You can't use persistent objects whose PersistenceManager has been closed.
The lifetime of the PM either has to span over all the code that will use the
persistent objects, or your query method needs to return objects which are
not persistent. There are typically two ways of handling the latter:
1. Use "value object" classes, and return value objects instead of persistent
objects.
2. Make sure the persistent objects are fully loaded into memory
(pm.retrieve()) and then transition them to transient (pm.makeTransient()).
Then they're no longer persistent and no longer tied to a PM. Note that if
you do this the objects lose their JDO identity.
In JDO 2.0 they've introduced methods to "detach" objects from a PM and later
"reattach" them to a different one. It works much like makeTransient() except
the objects don't lose their identity.
I very much want to upgrade TJDO to support JDO 2.0, but it's been hard to find
the time. I have added most of the new JDO 2.0 Query features though.
HTH,
Mike
Hi Mike,
I very much appreciate your help over the past few weeks!
If I'm understanding you correctly, the returnColl object that is returned at the end of the method is a persistent object. One of your suggestions is to make returnColl a non persistent object.
Regarding pm.retrieve and pm.transient, am I use to these methods to load returnColl completely into memory and then transition it to transient, and finally pass it back at the end of the method.
Could you confirm the above, and provide an example. That would be great.
Thanks...
returnColl is not itself persistent, but the objects returned by the Query are
persistent and you return them in the collection.
The makeTransient approach would look something like this:
Collection objColl = (Collection)q.execute();
for (Object obj : objColl)
{
pm.retrieve(obj);
pm.makeTransient(obj);
returnColl.add(obj);
}
Mike
Mike,
Could you expand on what you meant by "objects losing their JDO identity" above if one uses retrieve/makeTransient way. I tried the method above but I'm getting a null pointer exception in my JSP code where I access the object returned.
Thanks..
chopras wrote:
> Could you expand on what you meant by "objects losing their JDO identity"
> above if one uses retrieve/makeTransient way.
After pm.makeTransient(obj), JDOHelper.getObjectId(obj) == null. Also
see section 5.5.1 of the JDO spec:
http://tjdo.sourceforge.net/docs/jdo101.pdf
I'm posting my new get() method here. As suggested, I used the retrieve and transient method calls before copying over the objects to returnColl. Nonetheless, I'm still getting a null pointer exception. Any ideas?
this.pm_ = pmf_.getPersistenceManager();
Collection objColl = null;
Collection returnColl = new ArrayList();
Transaction tx = pm_.currentTransaction();
Query q = null;
try{
tx.begin(); //xact boundary begins here
...
objColl = (Collection) q.execute();
//returnColl.addAll(objColl);
for (Iterator it = objColl.iterator(); it.hasNext(); )
{
Object obj = it.next();
pm_.retrieve(obj);
pm_.makeTransient(obj);
returnColl.add(obj);
}
q.close(objColl);
tx.commit(); //commit, xact boundary ends here
}finally
{
//make sure to rollback the transaction if still active
if(tx.isActive())
tx.rollback();
pm_.close();
}
//pm_.close();
return returnColl;
I think you'll need to pursue the NullPointerException to the source based
on its stack trace.
Sorry to split this over two, please see above: I am not really performing any other operations on "obj" beyond adding it over to "returnColl".