如何防止 Grails 在删除父项时不删除子项?

How to prevent from Grails not to delete child while deleting parent?

作者和书是一对多的关系,一个作者有很多书..

我有这样的域 class

Author.groovy

class Author {

    String authorName;
    String authorAddress;
    String authorCNIC;

    static hasMany = [books:Book]

    static constraints = {

        books(nullable: true)
    }
}

Book.groovy

class Book {

    String bookName;
    String Isbn;

    static belongsTo = [author:Author]

    static constraints = {

        author(nullable: true)
    }



}

现在当我调用这个函数时

def deleteauthor()
    {
        def id=params.id
        Author author = Author.findById(id);
        author.delete(flush: true)
        render "Author Deleted"
    }

它会删除作者及其所有子书..我不想要这种行为,我希望它不能删除作者和书籍并显示消息不能删除作者,首先删除书籍...请告诉我如何这样做吗?

在您的 Author 模型中,您应该将 cascade: 'none' 添加到约束中:

class Author {

    String authorName;
    String authorAddress;
    String authorCNIC;

    static hasMany = [books:Book]

    static mapping = {
        cascade: 'none'
    }
}

这会阻止删除图书,并且只会将 author_id 设置为空。

更新:

设置cascade 'none'似乎也会禁用级联保存。 因此,一种选择是在每个添加的图书实例上手动调用 save

我想到的其他事情:

您可以将级联设置为仅在 save-update 上工作,但是当删除 Author 时会出现约束违反异常,因为无法在 Hibernate 上设置 on delete set null。我们可以在 beforeDelete.

上手动完成
class Author {

    String name;

    static hasMany = [books:Book]

    static mapping =  {
        books  cascade: 'save-update'
    }

    def beforeDelete() {
        Book.withNewSession {
            Book.findAllByAuthor(this).each {
              it.author = null
              it.save(flush: true)
            }
        }
   }
}

虽然不是很漂亮,但似乎有效。

由于我的声誉,我不能发表评论,但我可以回答。当您删除作者时它会删除书籍的原因是因为您在作者域上设置了 "belongsTo"。这决定了谁 "owns" 关系以及如何处理级联。

您可以看到以下内容:

具体来说:

Cascading

As with other relationships, mastering collections means mastering their cascading behaviour. The first thing to note is that saves are always cascaded from the parent to its children, even if there is no belongsTo specified. If that’s the case, is there any point to using belongsTo? Yes.

Consider what happens if we execute this code in the console after we have added the author and his books:

class Book {
  String title

  static constraints = {
    title(blank: false)
  }

}

class Author {
  String name
  Location location

  static hasMany = [ books: Book ]
}

def a = Author.get(1)
a.delete(flush: true)

println Author.list()*.name
println Book.list()*.title
The output looks like this:


[]
[Empire, Colossus]

In other words, the author has been deleted, but the books haven’t. That’s where belongsTo comes in: it ensures that deletes are cascaded as well as saves. Simply by adding the line static belongsTo = Author to Book, the above code will print empty lists for Author and Book. Simple, right? In this case, yes, but the real fun is only just beginning.

删除 belongsTo 应该会在删除作者时停止级联删除,但会留下书籍。我认为如果有相关实体但现在不记得如何删除,有一种方法会导致删除错误。这至少可以保护您免受级联删除。

我认为你可以将 'Author author' 添加到 Book 以保持关系。