操作在POGO上保存在Grails中

时间:2014-01-18 14:26:43

标签: grails gorm

我是Grails的初学者,当我尝试保存POGO时遇到问题

我创建了1个域类

class Book {
    String title
}

然后,我自动生成了控制器和视图。 现在,我希望能够通过单击“创建”创建一本包含代码的书(我知道可以直接使用生成的代码,但对于我的示例,我想通过代码来完成)。为此,我在控制器中修改了“save(Book bookInstance)”方法,就像这样

@Transactional
def save(Book bookInstance) {
    def book = new Book(title:"New Grails Book").save()

但是,当我转到URL localhost:8080 / myApp / book / create然后我点击“创建”时,我有错误

message -> /myApp/WEB-INF/grails-app/views/book/save.jsp
description -> The requested resource is not available.

当我把这段代码放在bootStrap中时,没关系,所以我不明白为什么它不在控制器中

1 个答案:

答案 0 :(得分:4)

如果域类中有hasMany属性,Grails会向域类添加Set属性并进行AST转换(因此它实际上存在于字节码中,并且可以看到Java)表示集合,当您添加belongsTo时,会添加该类型的字段。所以就像你有这个代码一样:

class Author {
   Set<Book> books
   static hasMany = [books: Book]
   String name
}

class Book {
   Author author
   static belongsTo = [author: Author]
   String title
}

AST xform使用map键作为字段名称,因此您可以使用任何有效的字段名称,但惯例是执行您所做的操作。

默认情况下,属性为nullable:false,因此您的代码不会保存Book实例,因为您未设置author属性。明确地执行此操作时,通常不会直接创建Book,而是使用动态Author方法将其添加到addToBooks的集合中。这将设置author字段返回引用,当您保存作者时,将对该书进行传递验证并保存。当您拥有new Book(params).save()之类的代码时,这一切都会为您处理,您可以直接执行此操作,例如。

Author author = ...
def book = new Book(title:"New Grails Book", author: author).save()

如果您使用的是生成的控制器和GSP,params地图中应该有作者ID,它可能是author.id,因此第一行将是

Author author = Author.get(params['author.id'])

但你可以添加

println params

在操作方法的顶部,查看所有提交的参数。

通常,您不希望查看保存调用的返回值,因为如果存在验证错误并且无法检索错误,则它将为null。所以改变

def book = new Book(...).save()

def book = new Book(...)
book.save()

现在您可以拨打book.hasErrors()book.getErrors()book.errors等来查看是否成功,如果没有,则会出现问题。

但这不是你所看到的确切问题,只是你解决问题时的问题。没有save.gsp,Grails也会查找save.jsp,并且在未找到的消息中容易混淆该名称。 save方法通过POST请求访问,通常来自create操作生成的表单,并且在验证失败时重新显示create.gsp提交的数据和错误消息,或者在保存成功时重定向到view操作。使用生成的代码时无需save.gsp