+3  A: 

According to App Engine docs, you should specify "mappedBy" in the owner of your relationship.

You may also want to read Max Ross's article or to have a look at my code which accesses parent (Discussion) from a child object (Message) which is fetched from a query

Dmitry
Indeed I forgot to add a mappedBy to User.contacts field<code>@Persistent(mappedBy="user") public List<Contact> contacts = new ArrayList<Contact>();</code>
raisercostin
A: 

Just posting the code with the correction Dmitry pointed out for easier reading:

import java.util.ArrayList;
import java.util.List;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import com.google.appengine.api.datastore.Key;

public class DatastoreJdoTest extends LocalServiceTestCase {
 @Autowired
 @Qualifier("persistenceManagerFactory")
 PersistenceManagerFactory pmf;

 @Test
 public void testBatchInsert() {
  Key contactKey;
  PersistenceManager pm = pmf.getPersistenceManager();
  try {
   pm.currentTransaction().begin();
   User user = new User();
   Contact contact = new Contact("contact1");
   user.contacts.add(contact);

   /*
    * With this an exception is thrown
    * 
    * Detected attempt to establish User(1)/Contact(2) as the parent of
    * User(1) but the entity identified by User(1) has already been
    * persisted without a parent. A parent cannot be established or
    * changed once an object has been persisted.
    * org.datanucleus.store.appengine.FatalNucleusUserException:
    * Detected attempt to establish User(1)/Contact(2) as the parent of
    * User(1) but the entity identified by User(1) has already been
    * persisted without a parent. A parent cannot be established or
    * changed once an object has been persisted. at
    * org.datanucleus.store
    * .appengine.DatastoreRelationFieldManager.checkForParentSwitch
    * (DatastoreRelationFieldManager.java:204)
    */
   //contact.user = user;
   Assert.assertNull(contact.key);
   pm.makePersistent(user);
   Assert.assertNotNull(contact.key);

   pm.currentTransaction().commit();

   contactKey = contact.key;
   //this assertion is broken. why ? 
   //Assert.assertNotNull(contact.user);
  } finally {
   if (pm.currentTransaction().isActive()) {
    pm.currentTransaction().rollback();
   }
  }
  Contact contact2 = pm.getObjectById(Contact.class, contactKey);
  Assert.assertNotNull(contact2);
  //this assertion is broken. why the contact don't store the parent user ?
  Assert.assertNotNull(contact2.user);
 }
}

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
class User {
 @PrimaryKey
 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 public Key key;
 @Persistent
 public String name;
 @Persistent(mappedBy = "user", dependent = "true")
 public List<Contact> contacts = new ArrayList<Contact>();
}

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
class Contact {
 @PrimaryKey
 @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
 Key key;
 @Persistent
 public String contact;
 @Persistent
 public User user;

 public Contact(String contact) {
  this.contact = contact;
 }
}
Tom