7

I have the following heriacy.

GrandParent --> Parent --> Child

Parent and Child use @Parent Ref<GrandParent> and @Parent Ref<Parent> to create there parent relationship.

I am trying to come of with a good way to do a cascading delete for GrandParent.

I of course I could load all the children, generate keys from them and delete by key. This seems terribly inefficient. Is there something where I could query by parent and turn the query results into a list of keys without having to do the full fetch?

Any thoughts, or third party libraries welcome.

Dan McGrath
  • 41,220
  • 11
  • 99
  • 130
Marc M.
  • 3,631
  • 4
  • 32
  • 53

2 Answers2

10

Basically, what Michael said, but here is the cleanest way I have found to do it.

ofy().delete().keys(ofy().load().ancestor(entityKey).keys().list()); // ancestor included

entityKey here is the key of the entity you want to delete (just in case that wasn't obvious)

  • this will handle any level of children, no matter their types.
  • as cheap of a call as you are going to get due to the use of a key only query keys()
Marc M.
  • 3,631
  • 4
  • 32
  • 53
  • 1
    Hi Marc, thanks, this worked for me. Small note however, you don't need the second delete call on the entityKey. The docs for ofy() state that the parent will be included in the list of keys, and therefore also deleted by the first call: Restricts result set only to objects which have the given ancestor somewhere in the chain. Doesn't need to be the immediate parent. The specified ancestor itself will be included in the result set (if it exists). – Pega88 Jun 15 '15 at 08:04
  • @Pega88 "The specified ancestor itself will be included in the result set" clause seems to have been added to the Objectify 5 documentation. Nice find! Thank you, I am using Objectify v5. – Marc M. Jun 16 '15 at 09:00
  • HI, will this code function correctly irrespective of the number of children? Will having a large number of children be an issue? – Sreekanth May 02 '16 at 13:01
  • @Sreekanth Yes, no reason it should't. Potentially a large query could fill up the App Engine memcache, but since this is a key only query I don't see that happening. – Marc M. May 02 '16 at 18:35
4

The issue here is that the Google Datastore is not really a relational database. it's a key-value store, so it's not so much truly connecting the 3 entities so much as just including references to each other. That means that there's no real way for a cascading delete.

As such, your best bet would be to query the children, fetch their entities, and then delete them one at a time (a good example can be found here)

Community
  • 1
  • 1
Michael
  • 53
  • 8