grailsgrails-2.5

grails 2.5.1 removeFrom one-to-many giving strange behavior (not removing)


I'm pretty much certain I'm doing something wrong since this obviously works. Simplified classes:

class Person {
  String name
  static hasMany = [cats:Cat]
}

class Cat {
  String name
  Person person
  static belongsTo = Person
  static constraints = {
    person(nullable:false)
  }
  String toString() {
    "${person.name}-${name}"
  }
}

Simple stuff, a person has many cats, cats must belong to only a single person.

Now when I do the following in a Service class, I get strange results:

delete(Cat cat) {
  Person owner = cat.person
  log.debug("Cats before removing ${cat} (id=${cat.id}): ${owner.cats} -- ${owner.cats*.id}")
  owner.removeFromCats(cat);
  log.debug("Removed from owner ${owner}, owner now has ${owner.cats} -- ${owner.cats*.id}")
  log.debug("Cat to delete is now: ${cat} and belongs to...  ${cat.person}")
  cat.delete(flush:true)
}

And the error is "object would be resaved, blah blah"

org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations)

The weird bit is the debug results, when called to remove cat "Fluffy" who's owned by "Bob":

Cats before removing Bob-Fluffy (id=1356): [Bob-Fluffy] -- [1356]
Removed from owner Bob, owner now has [null-Fluffy] -- [1356]
Cat to delete is now: null-Fluffy and belongs to...  null

What's going on that "removeFrom" isn't actually removing the object from the collection? I cleaned and recompiled. Pretty much at a loss as to why I can't delete this object.


Solution

  • It looks like what was happening in my case is that cat.person has getting stale somehow, even though it's the first thing in the method. Calling cat.refresh() didn't work, but calling owner.refresh() after extracting it from the cat.