2
votes

I'm trying to remove several objects from another based on a "status". I keep getting "Deleted object would be re-saved by cascade..." error.

I've search for this problem, read all the posts, tried the various suggestions but still can't get it to work.

I have two domains that reference each other. Here's the code. Hopefully someone can tell me what I'm doing wrong. And, I'm a new-comer to Grails. Had it dumped on me, so I'm still learning.

class Room {    
    static def hasMany = [devices : Device]
    static def hasOne = [status: RoomStatus]
    Integer roomId
    String name
    static constraints = {
        roomId unique: true
    }
    static mapping = {
        devices sort:'id', order: 'asc'
    }
}
class Device {
    static def belongsTo = [room: Room]
    static def hasOne = [status: DeviceStatus]
    Integer deviceId
    String name
    static constraints = {
        deviceId nullable: true, unique: true
    }
    static mapping = {
    }
}

Here's the method I'm using to remove all the devices in the "deleted" state from the room. It is in the Room controller:

def removeDeletedDevices(Long id) {
    def roomInstance = Room.get(id)
    if (!roomInstance) {
        // redirect to error page
        return
    }
    for (def device : roomInstance.devices) {
        if (true == device.status.toString().equals("Deleted")) {
            try {
                device.delete(flush: true)
            } catch (DataIntegrityViolationException e) {
                // report error
                break;
            }
        }
    }
    // redirect to report page.
}

I've tried

  • roomInstance.removeFromDevices(device) before the delete.
  • beforeDelete in the Device controller

No luck so far. What am I doing wrong?

1
Possible duplicate here. - dmahapatro

1 Answers

2
votes

You should configure the cascading behavior of an association. Add devices cascade:"all-delete-orphan" to mapping

class Room {    
    static def hasMany = [devices : Device]

    static constraints = {
        ......
    }
    static mapping = {
        devices cascade:"all-delete-orphan"
        ......
    }
}

And in action use the following snippet for delete.

EDITED

def devices = Device.findAllByStatusAndRoom("Deleted", roomInstance)
devices.each {
   roomInstance.removeFromDevices(it)
}