dildik
dildik

Reputation: 405

Weird Hibernate / Gorm behavior in Grails Application

I have a pretty simple relation, where normally a cascading delete should work. My relation looks like this:

enum StatusName {
    PENDING, SENDING, SENT
}

abstract class Notification {
    StatusName status = StatusName.PENDING
    Date dateCreated
    Date scheduledDate
    String text = ""
    User recipient
    boolean hasBeenSeen = false

    static belongsTo = [
        selectedChannel: SelectedChannel
    ]

    static constraints = {
        status blank: false, 
            inList:[StatusName.PENDING, StatusName.SENDING, StatusName.SENT]
        scheduledDate nullable: true
        text size: 0..1000
        recipient nullable: true 
    }

    def beforeInsert() {
        if(!recipient) { 
            recipient = selectedChannel?.user
        }
    }

}

And here the others class:

package de.carmeq.carmob

class SelectedChannel {

    static hasMany = [
        notifications: Notification
    ]

    static belongsTo = [
        channel: Channel,
        user: User,
        notificationType: NotificationType
    ]

    static constraints = {
        channel blank: false,
        user blank: false,
        notificationType blank: false, unique: ['channel', 'user']
    }
}

I want to delete all selectedChannels of a given user, so I do the following:

Collection<SelectedChannel> selectedChannels = SelectedChannel.findAllByUser(greedyUser)
selectedChannels*.delete()

But this causes the following error:

Referential integrity constraint violation: "FK237A88EBC25A325D: PUBLIC.NOTIFICATION FOREIGN KEY(SELECTED_CHANNEL_ID) REFERENCES PUBLIC.SELECTED_CHANNEL(ID)"; SQL statement:

delete from selected_channel where id=? and version=? [23503-164]

Even if I delete all notifications like this:

Collection<Notification> notifications = Notification.findAllByRecipient(greedyUser)
notifications*.delete()

I get the same error...

Greetings

Upvotes: 1

Views: 147

Answers (1)

coderLMN
coderLMN

Reputation: 3076

Add this mappings closure to SelectedChannel Domain:

static mapping = {
    notifications cascade: 'all-delete-orphan'
}

And delete selectedChannels like this:

Collection<SelectedChannel> selectedChannels = SelectedChannel.findAllByUser(greedyUser)
selectedChannels.each{sc->
    sc.notifications.each{nt->
        sc.removeFromNotifications(nt)
    }
    sc.delete()
}

If selectedChannels is also referenced in User or NotificationType Domain, use removeFrom method to clear the references first.

Upvotes: 1

Related Questions