Grails Quartz Job升级后没有Hibernate会话,导致LazyInitializationException
我已将 Grails 1.0.4 应用程序升级到 1.1.1。升级后,在执行 Quartz 作业(使用 Quartz 插件 0.4.1)时,我反复出现异常。该插件用于通过服务使用 Simple 和 Cron 触发器手动调度作业(下面解释代码):
class SchedulerService implements InitializingBean
{
static scope = 'singleton'
...
def schedule(def batch) {
JobDetail job = new JobDetail(uniqueId, groupName, BatchJob.class, false, false, true)
job.jobDataMap.put("batchId", batch.id)
SimpleTrigger trigger = new SimpleTrigger(triggerId, triggerGroup, 0)
SchedulerFactory factory = new SchedulerFactory()
factory.initialize(properties)
Scheduler scheduler = factory.getScheduler()
scheduler.scheduleJob(job, trigger)
}
...
}
我的 BatchJob 作业设置如下:
class BatchJob implements Job, InterruptableJob
{
static triggers = {}
void execute(JobExecutionContext context) {
def batch = Batch.get(context.jobDetail.jobDataMap.getLongValue("batchId"))
// the next line is "line 49" from the stack trace below
def foo = batch.batchStatus.description
}
}
这是 Batch.groovy(域)的缩写定义:
class Batch
{
BatchStatus batchStatus // relationship
}
但是,当 schedulerService .schedule()
使用现有的保存的批次调用,我收到以下异常:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:86)
at org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsHibernateUtil.unwrapProxy(GrailsHibernateUtil.java:311)
at org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsHibernateUtil$unwrapProxy.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
...
<b>at BatchJob.execute(BatchJob.groovy:49)</b>
...
我已尝试以下操作来解决此问题,但没有一个起作用:
- 我指定了
static fetchMode = [ batchStatus: 'eager']
在我的 Batch 域类上, - 我在我的 Batch 域类上使用了
static mapping = { columns { batchStatus lazy:false }}
- 我尝试使用
batch.attach()
在作业中调用Batch.get()
后,
我无法在这种情况下使用 BatchJob.triggerNow()
,因为这只是几个示例之一 - 其他示例仍然由服务调度,但可能被调度为 cron 作业或其他方式。我应该提到的是,我在升级 Grails 时也升级了 Quartz 插件;之前的 Quartz 版本是 0.4.1-SNAPSHOT(与升级版本相反,仅为 0.4.1)。
如何让 Hibernate 会话在这些手动触发的 Quartz 作业中正常工作?
我也已将此问题发送到 grails-user 邮件列表,对于像这样的更小众问题,该列表似乎引起了更多的反应。如果有人出来的话,我会用答案更新这个问题。 这是一个链接。
I've upgraded a Grails 1.0.4 application to 1.1.1. After upgrading, I'm repeatedly getting Exceptions when executing my Quartz jobs (using Quartz plugin 0.4.1). The plugin is used to manually schedule jobs using Simple and Cron Triggers via a service (paraphrased code below):
class SchedulerService implements InitializingBean
{
static scope = 'singleton'
...
def schedule(def batch) {
JobDetail job = new JobDetail(uniqueId, groupName, BatchJob.class, false, false, true)
job.jobDataMap.put("batchId", batch.id)
SimpleTrigger trigger = new SimpleTrigger(triggerId, triggerGroup, 0)
SchedulerFactory factory = new SchedulerFactory()
factory.initialize(properties)
Scheduler scheduler = factory.getScheduler()
scheduler.scheduleJob(job, trigger)
}
...
}
My BatchJob job is set up as follows:
class BatchJob implements Job, InterruptableJob
{
static triggers = {}
void execute(JobExecutionContext context) {
def batch = Batch.get(context.jobDetail.jobDataMap.getLongValue("batchId"))
// the next line is "line 49" from the stack trace below
def foo = batch.batchStatus.description
}
}
Here's an abbreviated definition of Batch.groovy (domain):
class Batch
{
BatchStatus batchStatus // relationship
}
However, when schedulerService.schedule()
is invoked with an existing, saved Batch, I receive the following Exception:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:86)
at org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsHibernateUtil.unwrapProxy(GrailsHibernateUtil.java:311)
at org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsHibernateUtil$unwrapProxy.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
...
<b>at BatchJob.execute(BatchJob.groovy:49)</b>
...
I've tried the following actions to fix this, but none have worked:
- I've specified
static fetchMode = [batchStatus: 'eager']
on my Batch domain class - I've used
static mapping = { columns { batchStatus lazy:false }}
on my Batch domain class - I've tried using
batch.attach()
after callingBatch.get()
in the Job
I can't use BatchJob.triggerNow()
in this instance, because this is only one of a couple examples - the others are still scheduled by the service, but might be scheduled as a cron job or otherwise. I should mention that I did upgrade the Quartz plugin as well when upgrading Grails; the previous Quartz version was 0.4.1-SNAPSHOT (as opposed to the upgraded version, just 0.4.1).
How do I get Hibernate sessions to work correctly in these manually-triggered Quartz Jobs?
I've also sent this question to the grails-user mailing list, as for a more niche issue like this, the list seems to elicit a bit more response. I'll update this question with an answer if one comes out of there. Here's a link.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用最新的 grails 版本 (Grails 2.0.0) 以及可能更早的版本,您可以使用此辅助方法来包装您的调用:
With the latest grails version (Grails 2.0.0) and maybe earlier versions, you can just wrap your call with this helper method:
我认为您可以调用
attach()
方法将会话添加到传递给计划作业的对象。I think you can call
attach()
method to add session to the object passing to the scheduled job.查看 jira 问题 165 (http://jira.codehaus.org/browse/GRAILSPLUGINS-165< /a>)Quartz 插件中也有一些线索(您可能想查看)此代码与 JMS 插件一起使用,似乎运行良好。
尝试
希望这有帮助。这对我有用。
Check out jira issue 165 (http://jira.codehaus.org/browse/GRAILSPLUGINS-165) There are also clues in the Quartz Plugin (which you may like to check out) This code was used with the JMS plugin which seems to work well.
try
Hope this helps. It worked for me.