开发者

Grails service not saving Domain Object When triggered by Message Queue

I have a grails application that has a service that creates reports. The report is defined as:

class Report {
    Date createDate
    String reportType
    List contents

    static constraints = {
    }
}

The service generates a report and populates contents as a list that is returned by createCriteria.

My problem is that my service claims to be saving the Report, no errors turn up, logging says that its all there, but when I go to call show from the controller on that report, it says contents is null.

Another relevant bit, my Service is called by an ActiveMQ message queue. The message originating from my report controller.

Controller:

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

My service that creates the report:

class ReportService {

static transactional = false
static expose = ['jms']
static destination = "Report"
开发者_JS百科
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)
           }
        }
   }
}

Is there something obvious that I'm missing here? My thought is that since all my unit tests work, that the hibernate context is not being passed through the message queue. But that would generate Exceptions wouldn't it? I've been beating my head on this problem for days, so a point in the right direction would be great.

Thanks,


You can't define an arbitrary List like that, so it's getting ignored and treated as transient. You'd get the same behavior if you had a def name field, since in both cases Hibernate doesn't know the data type, so it has no idea how to map it to the database.

If you want to refer to a collection of Results, then you need a hasMany:

class Report {
   Date createDate
   String reportType

   static hasMany = [contents: Result]
}

If you need the ordered list, then also add in a List field with the same name, and instead of creating a Set (the default), it will be a List:

class Report {
   Date createDate
   String reportType

   List contents
   static hasMany = [contents: Result]
}

Your unit tests work because you're not accessing a database or using Hibernate. I think it's best to always integration test domain classes so you at least use the in-memory database, and mock the domain classes when testing controllers, services, etc.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜