用户填写表格,为报告生成设置参数。他提交表单,服务器验证参数,向用户返回一切正常的消息并生成报告。报告生成完成后,用户会收到包含报告链接的电子邮件。
在grails中实现这一目标的正确方法是什么? 目前我有一个生成报告的服务,它看起来像这样:
@Transactional
class AnalyticsService {
ExecutorService executor = Executors.newSingleThreadExecutor()
def buildExportAndSendMail() {
executor.execute {
//GENERATE REPORT AND SEND MAIL. USES GORM.
}
}
@PreDestroy
void shutdown() {
executor.shutdownNow()
}
}
我的控制器操作如下所示:
def generateReport(ReportParams command) {
if(!command.hasErrors()) {
analyticsService.buildExportAndSendMail()
render([success:true, html:"Your report is being generated."] as JSON)
} else {
...
}
}
但是,在尝试访问域对象字段时,服务会抛出错误:
Exception in thread "pool-8-thread-1"
Error |
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
在grails中这样做的正确方法是什么?
答案 0 :(得分:1)
这里的问题是你正在创建一个新线程并且它没有绑定到Hibernate会话。创建一个很容易。使用哪个域类并不重要。例如:
def buildExportAndSendMail() {
executor.execute {
SomeDomainClass.withNewSession { session ->
//GENERATE REPORT AND SEND MAIL. USES GORM.
}
}
}
您可以在documentation中详细了解withNewSession
。
答案 1 :(得分:1)
我可能会用grails quartz plugin添加一份工作:
class ReportJob {
def execute () {
// create report
// mail report
}
}
然后使用
触发作业ReportJob.triggerNow (Map params)
优点是,您不需要显式处理线程或会话内容。