So this can be traced down to UserGameProfileGetter.getCurrentUserGameProfile(PersistenceManager, String), which does the following, if and only if the UGP does not yet exist:
1. Get a UserData from the datastore (with the same persistence manager),
2. Get a GameData from the datastore (with the same persistence manager),
3. Create a new UserGameProfileData,
4. Write the UserGameProfileData to the datastore (with the same persistence manager),
5. Update the UserData to refer to the UserGameProfileData,
6. Update the GameData to refer to the UserGameProfileData.
Then, in KeyValuePairGetter:51, it calls pm.close() which brings everything crashing down.
It seems like the problem is that the *same* persistence manager is being used to write to both the GameData *and* the UserGameProfileData. The problem goes away if you change step #1 and #2 to each create their own PM (trivial -- just remove the PM argument to the call).
I'm quite surprised about this. I knew that a *transaction* could only apply to a single entity group, but I had no idea that a persistence manager could only apply to one entity group for its lifetime. I am surprised that this hasn't come up elsewhere. We should be on the look out for it.
So this can be traced down to UserGameProfile Getter. getCurrentUserG ameProfile( PersistenceMana ger, String), which does the following, if and only if the UGP does not yet exist: Data, Data, Data.
1. Get a UserData from the datastore (with the same persistence manager),
2. Get a GameData from the datastore (with the same persistence manager),
3. Create a new UserGameProfile
4. Write the UserGameProfileData to the datastore (with the same persistence manager),
5. Update the UserData to refer to the UserGameProfile
6. Update the GameData to refer to the UserGameProfile
Then, in KeyValuePairGet ter:51, it calls pm.close() which brings everything crashing down.
It seems like the problem is that the *same* persistence manager is being used to write to both the GameData *and* the UserGameProfile Data. The problem goes away if you change step #1 and #2 to each create their own PM (trivial -- just remove the PM argument to the call).
I'm quite surprised about this. I knew that a *transaction* could only apply to a single entity group, but I had no idea that a persistence manager could only apply to one entity group for its lifetime. I am surprised that this hasn't come up elsewhere. We should be on the look out for it.