2015-12-02 103 views
0

我必须从我的域调用我的控制器的一种方法。我试图找到一些答案,但我没有找到任何东西,我不确定是否有可能。对不起,如果我的问题是错误的,但在我有我必须找到一个解决方案,因为我已经在我的域中的方法beforeInsert()内部做的问题。如何在grails中调用域内的服务方法?

这是我尝试运行该项目时的错误:

|错误2015-12-02 10:59:29,210 [localhost-startStop-1]错误hibernate.AssertionFailure - 发生断言失败(这可能表示Hibernate中存在错误,但更可能是由于会话的不安全使用) 消息:在com.xxxx进入空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

不确定静态调用您的服务是否正确,因为它可能没有被grails应用程序正确初始化。只需将您的服务连接到您的控制器和域名,然后按正常方式打电话。 – shuttsy

+0

你能举个简单的例子吗?我在grails中是新的.. –

回答

2

您的问题的主题有误导性:您说您需要从域中调用控制器方法,但是您的代码说的是您试图从域和控制器调用服务方法。

您无法从域调用控制器方法,在概念上是错误的,但是您也需要请求调用控制器,并且您没有在域中拥有它。

但是,你要做的是实现它的方式:将逻辑留给服务并从控制器和域调用它。但是你做错了。

在你需要声明的服务控制器,所以春天将注入到你的控制器,就像这样:

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

您可以在服务属性的声明中使用的实际类型,而不是高清的,但重要的是,属性名称是服务的“逻辑名称”:类名称,但小写的第一个字母。这样,财产将在春季注入。

您应该为“用户”更改变量“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的解决方案)。

+0

我做了你的步骤,但我有同样的错误.... –

+0

问题可能是你在执行beforeInsert事件中的查询。我不明白你在服务中想做什么:你将用户列表传递给calculate方法,而不是你刚刚创建的用户。如果你想要实现的是在创建一个新用户(危险)时对所有用户执行一些计算,那么你应该使用像jms这样的分离系统来在不同的线程中创建该进程,然后在保存控制器的方法或更好,从服务中添加一个“保存用户”方法。 – ncerezo

+0

hmmmm。好。如何匹配我刚刚创建的用户?谢谢 –

相关问题