删除域对象时获取“参照完整性约束违规” [英] Getting 'Referential integrity constraint violation' when deleting domain object

查看:87
本文介绍了删除域对象时获取“参照完整性约束违规”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我疯狂的宇宙中,一个房间可以有许多椅子和椅子可以属于许多房间。
在grails中,它看起来像这样。

  class Room {
字符串名称
static hasMany = [椅子:椅子]
静态约束= {
}
}
类椅子{
字符串名称
静态约束= {
}
}

我想要删除椅子并自动删除所有房间域中的椅子参考拥有那把椅子的物体。
我已经成功了,但有一个我不喜欢的修复程序。在ChairController中,我做了以下操作:

  def deleleChair(){
def chairToDelete = Chair.get(params.id )
Room.findAll()。each {room->
if(room.chairs.contains(chairToDelete)){
room.removeFromChairs(chairToDelete)
room.save(failOnError:true)
}
}
chairToDelete.delete(params.chairId)
}

是否有一个hibernate配置我需要设置,以便它自动执行此操作?这似乎是在现实世界中非常普遍的情况。我不想实现同一段代码,当我可能决定时,(疯狂的例子)Car域对象可以有许多椅子。



我试过使用grails事件推送插件。

  class ChairService {
@ grails.events我有一个ChairService,它有一个在gorm中侦听beforeDelete事件的动作。 .Listener(topic ='beforeDelete',namespace =gorm)
def handleDeletedChair(Chair chair){
Room.findAll()。each {room->
if(room.chairs.contains(chairToDelete)){
room.removeFromChairs(chairToDelete)
room.save(failOnError:true,flush:true)
}
}


尝试,但是当它返回到ChairController以执行实际的主席删除时,删除操作仍然认为对Room的引用仍然存在,并引发一个

<$ p $由JdbcSQLException导致:参照完整性约束冲突:FK4ACA6A6151428364:PUBLIC.ROOM_CHAIR FOREIGN KEY(CHAIR_ID)REFERENCES PUBLIC.CHAIR(ID); SQL语句:

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



我希望这个逻辑与主席分开,主席不应该对房间不要。



  import 解决方案

grails.events.Listener
导入groovy.sql.Sql

class ChairService {
def dataSource // autowired

@Listener(topic ='beforeDelete ',namespace ='gorm')
def handleDeletedChair(ChairToDelete){
new Sql(dataSource).execute('DELETE FROM room_chair WHERE chair_id =?',[chairToDelete.id])
返回true


code $
$ b $ p $因为这是SQL它可能是依赖的在你使用的数据库上(我用H2测试过)。

In my crazy universe a Room can have many chairs and chairs can 'belong' to many rooms. In grails it looks like this. Chairs should not know which room they belong to.

class Room {
    String name
    static hasMany = [chairs: Chair]
    static constraints = {
    }
}
class Chair {
    String name
    static constraints = {
    }
}

I want to delete a chair and automatically remove any references of chairs in all room domain objects that have that chair. I have succeeded, but with a fix that i dont like. In the ChairController i did the following

def deleleChair(){
    def chairToDelete = Chair.get(params.id)
    Room.findAll().each {room->
        if(room.chairs.contains(chairToDelete)){
            room.removeFromChairs(chairToDelete)
            room.save(failOnError:true)
        }
    }
    chairToDelete.delete(params.chairId)
}

Is there a hibernate config that I need to set so that it does this automatically? It seems like something very common in real world scenarios. I would not want to implement the same piece of code, when I probably decide,(crazier example) that a Car domain object can have many chairs.

I have tried to use the grails event push plugin. I had a ChairService with an action that listened for beforeDelete events in gorm.

class ChairService {
    @grails.events.Listener(topic = 'beforeDelete', namespace = "gorm")
    def handleDeletedChair(Chair chair){
         Room.findAll().each {room->
            if(room.chairs.contains(chairToDelete)){
                room.removeFromChairs(chairToDelete)
                room.save(failOnError:true, flush:true)
            }
        }
    }
}

This function is called whenever a chair delete is attempted, but when it return to the ChairController so as to do the actual chair deletion, the delete action still thinks that the reference to Room is still there and throws a

 Caused by JdbcSQLException: Referential integrity constraint    violation:"FK4ACA6A6151428364: PUBLIC.ROOM_CHAIR FOREIGN KEY(CHAIR_ID) REFERENCES PUBLIC.CHAIR(ID)"; SQL statement:

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

I want this logic to be separate from the Chair, the chair should never no about the rooms.

解决方案

A simple solution would be to use standard SQL:

import grails.events.Listener
import groovy.sql.Sql

class ChairService {
    def dataSource // autowired

    @Listener(topic='beforeDelete', namespace='gorm')
        def handleDeletedChair(Chair chairToDelete) {
        new Sql(dataSource).execute('DELETE FROM room_chair WHERE chair_id=?', [chairToDelete.id])
        return true
    }
}

As this is SQL it may be dependent on the database you are using (I tested with H2).

这篇关于删除域对象时获取“参照完整性约束违规”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆