MODEL OBJECTS:
@PersistenceCapable(detachable = "true")
@FetchGroup(name = "children", members = { @Persistent(name =
"_Children") })
public class Parent {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key _ID;
@Persistent
private String _Name;
@Persistent(mappedBy = "_Parent")
@Element(dependent = "true")
private Set<Child> _Children = new HashSet<Child>();
public Parent(Key ID, String Name)
{
_ID = ID;
_Name = Name;
}
//Getters removed
}
@PersistenceCapable(detachable = "true")
public class Child {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key _ID;
@Persistent
private Parent _Parent;
@Persistent
private Key _ParentKey;
@Persistent
private String _Value;
public Child(Key ID, Parent parent, String value)
{
_ID = ID;
_ParentKey = parent.GetID();
_Parent = parent;
}
}
TEST CODE:
private static PersistenceManagerFactory _pmf = null;
public String greetServer(String input) throws
IllegalArgumentException {
if(_pmf == null)
_pmf =
JDOHelper.getPersistenceManagerFactory("transactions-
optional");
Key parentKey =
KeyFactory.createKey(Parent.class.getSimpleName(),
"abc"); //We only ever create one parent object and then retrieve it
ArrayList<Key> keyList = new ArrayList<Key>();
keyList.add(parentKey);
List<Parent> p = FetchAndDetachParent(keyList);
if(p == null)
{
Parent pt = new Parent(parentKey, "hello");
ArrayList<Parent> list = new ArrayList<Parent>();
list.add(pt);
AddOrAttachParent(list);
}
else //If the parent has already been created, add children to
it
{
String childKeyString = UUID.randomUUID().toString();
Parent pt = p.get(0);
Key childKey = KeyFactory.createKey(pt.GetID(),
Child.class.getSimpleName(), childKeyString);
Child ch = new Child(childKey, pt, "hello");
pt.GetChildren().add(ch);
ArrayList<Parent> list = new ArrayList<Parent>();
list.add(pt);
AddOrAttachParent(list);
}
return "all ok";
}
public List<Parent> FetchAndDetachParent(List<Key> Keys)
{
PersistenceManager pm = _pmf.getPersistenceManager();
pm.setDetachAllOnCommit(true);
pm.getFetchPlan().addGroup("children");
Transaction tx = pm.currentTransaction();
Query query = null;
try {
tx.begin();
query = pm.newQuery(Parent.class);
query.setFilter("_ID == :keyList");
List<Parent> results = (List<Parent>)query.execute(Keys);
if(results.size() == 0)
{
tx.commit();
return null;
}
else
{
tx.commit();
return results;
}
} finally {
query.closeAll();
if (tx.isActive())
{
tx.rollback();
}
pm.close();
}
}
public void AddOrAttachParent(List<Parent> parents)
{
PersistenceManager pm = _pmf.getPersistenceManager();
Transaction tx = pm.currentTransaction();
try
{
tx.begin();
//pm.makePersistent(parents.get(0));
pm.makePersistentAll(parents); //If I comment out this
line and
uncomment the above one, everything is fine. If not, then sometimes
this works, and sometimes it throws.
tx.commit();
}
finally
{
if (tx.isActive())
{
tx.rollback();
}
pm.close();
}
}
The exception is as follows:
SEVERE: [1269368147119000] javax.servlet.ServletContext log: Exception
while dispatching incoming RPC call
com.google.gwt.user.server.rpc.UnexpectedException: Service method
'public abstract java.lang.String
com.mike.test.client.GreetingService.greetServer(java.lang.String)
throws java.lang.IllegalArgumentException' threw an unexpected
exception: javax.jdo.JDOUserException: One or more instances could not
be made persistent
NestedThrowables:
java.lang.NullPointerException
at
com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:
378)
at
com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:
581)
at
com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:
188)
at
com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:
224)
at
com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:
62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:713)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:
487)
at org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1093)
at
com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:
51)
at org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1084)
at
com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:
43)
at org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1084)
at
com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:
121)
at org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1084)
at
org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:
360)
at
org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:
216)
at
org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:
181)
at
org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:
712)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:
405)
at
com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:
70)
at
org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:
139)
at com.google.appengine.tools.development.JettyContainerService
$ApiProxyHandler.handle(JettyContainerService.java:352)
at
org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:
139)
at org.mortbay.jetty.Server.handle(Server.java:313)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:
506)
at org.mortbay.jetty.HttpConnection
$RequestHandler.content(HttpConnection.java:844)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:644)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381)
at
org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:
396)
at org.mortbay.thread.BoundedThreadPool
$PoolThread.run(BoundedThreadPool.java:442)
Caused by: javax.jdo.JDOUserException: One or more instances could not
be made persistent
NestedThrowables:
java.lang.NullPointerException
at
org.datanucleus.jdo.JDOPersistenceManager.makePersistentAll(JDOPersistenceManager.java:
737)
at
org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManager.access
$001(DatastoreJDOPersistenceManager.java:39)
at org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManager
$1.call(DatastoreJDOPersistenceManager.java:100)
at org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManager
$1.call(DatastoreJDOPersistenceManager.java:99)
at org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManager
$BatchManagerWrapper.call(DatastoreJDOPersistenceManager.java:125)
at org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManager
$BatchManagerWrapper.access$200(DatastoreJDOPersistenceManager.java:
121)
at
org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManager.makePersistentAll(DatastoreJDOPersistenceManager.java:
98)
at
com.mike.test.server.GreetingServiceImpl.AddOrAttachDecks(GreetingServiceImpl.java:
111)
at
com.mike.test.server.GreetingServiceImpl.greetServer(GreetingServiceImpl.java:
56)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at
com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:
100)
at
com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:
562)
... 30 more
Caused by: java.lang.NullPointerException
at org.datanucleus.sco.SCOUtils.attachAddNewElements(SCOUtils.java:
743)
at org.datanucleus.sco.simple.Set.attachCopy(Set.java:234)
at
org.datanucleus.store.fieldmanager.AttachFieldManager.storeObjectField(AttachFieldManager.java:
205)
at
org.datanucleus.state.AbstractStateManager.providedObjectField(AbstractStateManager.java:
1037)
at com.mike.test.server.model.Parent.jdoProvideField(Parent.java)
at com.mike.test.server.model.Parent.jdoProvideFields(Parent.java)
at
org.datanucleus.state.JDOStateManagerImpl.provideFields(JDOStateManagerImpl.java:
2715)
at
org.datanucleus.state.JDOStateManagerImpl.internalAttachCopy(JDOStateManagerImpl.java:
4055)
at
org.datanucleus.state.JDOStateManagerImpl.attachCopy(JDOStateManagerImpl.java:
3987)
at
org.datanucleus.ObjectManagerImpl.attachObjectCopy(ObjectManagerImpl.java:
1778)
at
org.datanucleus.ObjectManagerImpl.persistObjectInternal(ObjectManagerImpl.java:
1260)
at
org.datanucleus.ObjectManagerImpl.persistObject(ObjectManagerImpl.java:
1175)
at
org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:
669)
at
org.datanucleus.jdo.JDOPersistenceManager.makePersistentAll(JDOPersistenceManager.java:
723)
... 44 more
--
You received this message because you are subscribed to the Google Groups
"Google App Engine for Java" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-appengine-java?hl=en.