How do you implement cascading delete in Objectify?
Asked Answered
P

2

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.

Pungent answered 19/10, 2014 at 20:32 Comment(0)
P
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()
Pungent answered 7/1, 2015 at 8:50 Comment(4)
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).Marquez
@Marquez "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.Pungent
HI, will this code function correctly irrespective of the number of children? Will having a large number of children be an issue?Tammara
@Tammara 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.Pungent
E
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)

Edger answered 17/12, 2014 at 22:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.