I'm working on a multi-user application where I'm using my own authentication / account scheme, but am running into trouble structuring accounts in GAE storage. Here's where I started and got tripped up:
- I'd like each user be a root level entity, and have all of the entities for that user be child entities, since transactions are almost always done on a single user. - I'd like the username for users to be their email address, which they can change at any time, but each user should have a system-assigned integer ID that never changes. Given this, I started creating Account entities at the root level, each with an "email" property containing their email address. My first problem came immediately, when trying to create an Account as follows: public boolean createAccount(final Account ac) { final DatastoreService ds = DatastoreServiceFactory.getDatastoreService (); final Transaction txn = ds.beginTransaction(); try { // see if an account with the same email already exists final Query q = new Query("Account"); q.addFilter("email", Query.FilterOperator.EQUAL, ac.getEmail()); final PreparedQuery pq = ds.prepare(txn, q); final boolean bCreated; if (0 < pq.countEntities(FetchOptions.Builder.withLimit(1))) { bCreated = false; } else { ds.put(EntityFactory.create(ac)); // EntityFactory just creates an entity of kind "Account" with the right fields set bCreated = true; } txn.commit(); return bCreated; } finally { if (txn.isActive()) txn.rollback(); } } The problem is, I can't query and update root level entities in a transaction, because that query doesn't contain an ancestor query, so there's no way for me to atomically check that an Account with a given email address doesn't exist, then create the account. I get "java.lang.IllegalArgumentException: Only ancestor queries are allowed inside transactions.". How do I solve this, given the following restrictions? - I don't want the email address to be the key for the entity, because then a user's email address can't change without copying their entire entity tree. - I don't want users to have a separate username from their email address that's used as the entity key, as they tend to forget usernames, so I find their email address to be convenient. - I don't want to create a dummy parent entity that all Accounts are under, because that would force all users to be in the same entity group, which would make transaction concurrency poor. Any thoughts? -- You received this message because you are subscribed to the Google Groups "Google App Engine" group. To view this discussion on the web visit https://groups.google.com/d/msg/google-appengine/-/5TUz9xKMX8YJ. To post to this group, send email to google-appengine@googlegroups.com. To unsubscribe from this group, send email to google-appengine+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en.