Grails服务不保存域对象由Message Queue触发时

时间:2011-02-18 15:20:33

标签: grails message-queue

我有一个grails应用程序,它有一个创建报告的服务。该报告定义为:

class Report {
    Date createDate
    String reportType
    List contents

    static constraints = {
    }
}

该服务生成报告并将contents填充为createCriteria返回的列表。

我的问题是我的服务声称正在保存报告,没有错误出现,日志记录说它全部存在,但是当我从控制器上调用show报告时,它说内容为空。

另一个相关位,我的服务由ActiveMQ消息队列调用。来自我的报告控制器的消息。

控制器:

class ReportController {

    def scaffold = Report

    def show = {
        def rep = Report.get(params.id)

        log.info("Report is " + (rep? "not null" : "null")) //says report is not null
        log.info("Report content is " + (rep.contents? "not null" : "null")) //always says report.contents is null.

        redirect(action: rep.reportType, model: [results: rep.contents, resultsTotal: rep.contents.size()])
    }
}

我创建报告的服务:

class ReportService {

static transactional = false
static expose = ['jms']
static destination = "Report"

void onMessage(msg) 
{
    this."$msg.reportType"(msg)
}

void totalQuery(msg) 
{       
   def results = Result.createCriteria().list {
       //This returns exactly what i need.
   }

   Report.withTransaction() {
       def rep = new Report(createDate: new Date(), reportType: "totalQuery", contents: results)

       log.info("Validation results: ${rep.validate()}")

       if( !rep.save(flush: true) ) {
           rep.errors.each {
                log.error(it)
           }
        }
   }
}

我有什么明显的遗漏吗?我的想法是,因为我的所有单元测试都工作,所以hibernate上下文没有通过消息队列传递。但那会产生例外不是吗?我已经在这个问题上打了好几天,所以在正确方向上的一点很好。

谢谢,

1 个答案:

答案 0 :(得分:3)

您不能像这样定义任意List,因此它会被忽略并被视为瞬态。如果你有def name字段,你会得到相同的行为,因为在这两种情况下Hibernate都不知道数据类型,所以它不知道如何将它映射到数据库。

如果您想引用一系列结果,那么您需要hasMany

class Report {
   Date createDate
   String reportType

   static hasMany = [contents: Result]
}

如果您需要有序列表,那么还要添加一个名称相同的List字段,而不是创建Set(默认值),它将是List

class Report {
   Date createDate
   String reportType

   List contents
   static hasMany = [contents: Result]
}

您的单元测试工作是因为您没有访问数据库或使用Hibernate。我认为最好始终集成测试域类,以便至少使用内存数据库,并在测试控制器,服务等时模拟域类。