Grails应用程序中奇怪的Hibernate / Gorm行为

时间:2013-03-12 20:37:36

标签: hibernate grails foreign-keys relational-database gorm

我有一个非常简单的关系,通常级联删除应该有效。我的关系看起来像这样:

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
        }
    }

}

这里是其他人的课程:

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']
    }
}

我想删除给定用户的所有selectedChannel,因此我执行以下操作:

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

但是这会导致以下错误:

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

从selected_channel删除,其中id =?和版本=? [23503-164]

即使我删除了所有这样的通知:

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

我得到同样的错误......

问候

1 个答案:

答案 0 :(得分:1)

将此映射关闭添加到 SelectedChannel 域:

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

并删除selectedChannels,如下所示:

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

如果UserNotificationType域中也引用 selectedChannels ,请先使用removeFrom方法清除引用。