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.

Reply via email to