我必须从我的域中调用我的控制器的一个方法。我试图找到答案,但我找不到任何答案,我不确定是否可行。对不起,如果我的问题是错误的,但在我所拥有的要求中,我必须找到一个解决方案,因为我已经在我的域中的beforeInsert()方法中做了。
尝试运行项目时出现错误:
|错误2015-12-02 10:59:29,210 [localhost-startStop-1]错误hibernate.AssertionFailure - 发生断言失败(这可能表示Hibernate中存在错误,但更可能是由于会话的不安全使用) 消息:com.xxxx条目中的null id(在发生异常后不刷新会话)
控制器方法:
def calculate(Integer max){
params.max = Math.min(max ?: 10, 100)
def users= User.findAllByType(null)
LicenceTypeService.calculate(users) //This call a service
redirect(action: "list", params: params)
}
在我的域名中:
protected void callCalculateWhencreateUser(){
def users= User.find("from User order by id desc")
LicenceTypeService.calculate(users) //This call a service
}
def beforeInsert() {
encodePassword()
callCalculateWhencreateUser()
}
在我的服务中:
def calculate(def users){
//logic code
}
答案 0 :(得分:3)
您的问题的主题是误导性的:您说您需要从域中调用控制器方法,但您的代码所说的是您尝试从域和控制器调用服务方法。
您无法从域中调用控制器方法,在概念上是错误的,但您还需要调用控制器的请求,而您在域中没有它。
但是,您要做的事实上是实现它的方法:将逻辑留给服务并从控制器和域中调用它。但是你做错了。
在控制器中你需要声明服务,所以spring会将它注入你的控制器,就像这样:
class MyController {
def licenceTypeService
def calculate(Integer max){
params.max = Math.min(max ?: 10, 100)
def users = User.findAllByType(null)
licenceTypeService.calculate( users )
redirect(action: "list", params: params)
}
}
您可以在服务属性的声明中使用实际类型而不是def,但重要的是属性名称是服务的“逻辑名称”:类名,但小写的第一个字母。这样财产将在春季注入。
您应该为“用户”更改变量“user”,它会让您认为是单个用户,但您使用的查找器会返回用户列表。
在域名上你需要做更多的工作。您需要以相同的方式注入服务,但是您需要将其添加到“瞬态”列表中,因此GORM不会尝试在数据库中为其创建字段或从数据库中检索它。
像这样:
class MyDomain {
def licenceTypeService
static transients = [ "licenseTypeService" ]
def beforeInsert() {
encodePassword()
licenceTypeService.calculate( this )
}
}
您的服务将是:
class LicenceTypeService {
def calculate( User user ) {
// perform some calculation
// do not call user.save() since this will be invoked from beforeInsert
}
def calculate( List<User> users ) {
// If this is performed on several users it should be
// done asynchronously
users.each {
calculate( it )
it.save()
}
}
}
希望有所帮助。
但是,根据您在计算方法中的操作(对于单个用户),它可以是User类的方法(这是一个更OO的解决方案)。