消息队列触发时Grails服务未保存域对象

消息队列触发时Grails服务未保存域对象,grails,message-queue,Grails,Message Queue,我有一个grails应用程序,它有一个创建报告的服务。该报告的定义如下: class Report { Date createDate String reportType List contents static constraints = { } } 该服务生成一个报告并将内容填充为createCriteria返回的列表 我的问题是,我的服务声称正在保存该报告,没有出现错误,日志记录说一切都在那里,但当我从该报告的控制器调用show时,它说内容为空

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

class Report {
    Date createDate
    String reportType
    List contents

    static constraints = {
    }
}
该服务生成一个报告并将
内容填充为
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上下文不会通过消息队列传递。但这会产生例外,不是吗?我已经在这个问题上绞尽脑汁好几天了,所以在正确的方向上找到一点就好了


谢谢,

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

如果要引用结果集合,则需要一个
hasMany

class Report {
   Date createDate
   String reportType

   static hasMany = [contents: Result]
}
如果您需要有序列表,则还可以添加一个同名的
列表
字段,而不是创建一个
集合
(默认设置),它将是一个
列表

class Report {
   Date createDate
   String reportType

   List contents
   static hasMany = [contents: Result]
}

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

如何找到保存的报告的id?我没有看到任何代码会将它传递到外部或记录它。
list
操作是否显示新创建的报告?应用程序使用自动生成的列表视图。点击身份证号码进入“显示”好的,谢谢你的澄清。我想我必须在这方面有一个新的计划。我只是感到困惑,因为我的测试是集成测试,它们通过了…如果您测试的逻辑主要与保存/查找相关,那么最好在集成测试中测试域类。在我看来,它就像一个贫血的领域模型。此外,单元测试将无法在几秒钟内运行()——这是它们的主要优势之一。对我来说,使用mockDomain()进行单元测试很好。