2013-03-12 20 views
1

我有一个非常简单的关系,其中通常级联删除应该工作。我的关系是这样的:Grails应用程序中奇怪的Hibernate/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 
     } 
    } 

}

在这里,其他类:

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

我想删除一个给定的所有selectedChannels用户,所以我做了以下操作:

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() 

我得到同样的错误...

问候

+0

抽象类是否在解决这个问题?我在我的代码中找不到任何问题... – Nadya 2013-03-12 20:40:56

+0

这是因为您正在删除'SelectedChannel'并存在'Notification'关联记录。您需要先删除该selectedchannel的所有通知。如果您将'Notification'更改为不是抽象类,它会起作用吗? – 2013-03-12 22:30:16

回答

1

添加此映射到封SelectedChannel域:

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

And del ETE selectedChannels这样的:

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

如果selectedChannels也在UserNotificationType域参考,使用removeFrom方法先清除引用。

+0

谢谢,但这并没有改变任何东西。同样的错误。 :( – Nadya 2013-03-13 11:25:25

+0

@ user1726376请看我更新的答案。 – coderLMN 2013-03-13 15:52:16