My application constructs a Parent
object in a static factory, along with it's predetermined Child
ren, and then starts up tasks to run some computation on the Child
ren, like so:
public static Parent make(User owner, List<Integer> data, int size) {
Parent result = new Parent(owner,data,size);
PersistenceManager pm = PersistenceSource.get();
Transaction tx = pm.currentTransaction();
try {
tx.begin();
result = pm.makePersistent(result);
for (int i=0; i<size; pm.makePersistent(new Child(result,i++)));
pm.close();
tx.commit();
} finally {
if (tx.isActive()) { tx.rollback(); result=null; }
}
if (result!=null) {
Queue q = QueueFactory.getDefaultQueue();
for (Child c : resu开发者_C百科lt.getChild()) {
q.add(url("/task/child").param("key", KeyFactory.keyToString(c.getKey())).method(Method.PUT));
}
}
pm.close();
return result;
}
however in the actual task
public void doPut(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
PersistenceManager pm = PersistenceSource.get();
Child c = pm.getObjectById(Child.class, KeyFactory.stringToKey(request.getParameter("key"))); //...
It dies trying to find the object:
Could not retrieve entity of kind Child with key Child(24)
org.datanucleus.exceptions.NucleusObjectNotFoundException: Could not retrieve entity of kind Child with key Child(24)
Any insights? Also, if it matters, the Parent-child relationship is defined by the parent as a field in the child (hence construction with the parent as an arg).
After some plugging around, the following will work to properly retrieve the desired Child
:
Key k = new KeyFactory
.Builder(Parent.class.getSimpleName(), Long.valueOf(request.getParameter("parent")))
.addChild(Child.class.getSimpleName(), Long.valueOf(request.getParameter("child")))
.getKey();
Child c = pm.getObjectById(Child.class, k);
I'm still a bit mystified coming from the non-DataStore world as to why the type + id is insufficient to fetch what I want. That seems equivalent to knowing table + primary key in SQL land, and the documentation seems to indicate that the key contains all the parent info, such that having it should be sufficient to do a direct pm.getObjectId(Child, KeyFactory./* etc */)
.
public Object retrieveChildByKey(Key parent, Class childClass, int idChild){
try{
pm = PMF.get().getPersistenceManager();
Key objectKey = KeyFactory.createKey(parent, childClass.getSimpleName(), idChild);
Object result = pm.getObjectById(childClass, objectKey);
return result;
}
catch (DatastoreTimeoutException ex) {
// Display a timeout-specific error page
message = "Timeout: An error has occurred: Was not possible to retrieve the Object";
System.out.println(message);
ex.printStackTrace();
}
catch(Exception ex){
message = "Timeout: An error has occurred: Was not possible to retrieve the Object";
System.out.println(message);
ex.printStackTrace();
}finally{
pm.close();
}
return null;
}
精彩评论