我正在尝试使用Quartz在Spring启动时安排一项工作。以下是我在下面使用的代码是我的配置...
问题:调用作业时,org.hibernate.LazyInitializationException:无法懒惰地初始化角色集合:
HCSchedulerFactoryBean:
@Autowired
HCJobFactory jobFactory;
@Autowired
DataSource dataSource;
@Autowired
PlatformTransactionManager transactionManager;
@Override
public void afterPropertiesSet() throws Exception
{
setJobFactory( jobFactory.getJobFactory() );
setDataSource( dataSource );
//setTransactionManager( transactionManager );
super.afterPropertiesSet();
}
//工作工厂:
@Component
public class HCJobFactory
{
@Autowired
ApplicationContext applicationContext;
public JobFactory getJobFactory()
{
HCSpringBeanJobFactory jobFactory = new HCSpringBeanJobFactory();
jobFactory.setApplicationContext( applicationContext );
return jobFactory;
}
}
// SpringBeanJobFactory
public final class HCSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware
{
private transient AutowireCapableBeanFactory beanFactory;
@Override
public void setApplicationContext( final ApplicationContext context )
{
beanFactory = context.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance( final TriggerFiredBundle bundle ) throws Exception
{
final Object job = super.createJobInstance( bundle );
beanFactory.autowireBean( job );
return job;
}
}
//在Quartz中安排的调度程序作业
@SuppressWarnings( { "unchecked", "rawtypes" } )
public Mailing saveAndScheduleMailing( Mailing mailing, Long runByUserId )
{
try
{
mailing = mailingDAO.saveMailing( mailing );
// schedule job
LinkedHashMap parameterValueMap = new LinkedHashMap();
parameterValueMap.put( "mailingId", mailing.getId() );
ProcessSchedule processSchedule = new ProcessSchedule();
processSchedule.setStartDate( new Date() );
processSchedule.setTimeOfDayMillis( new Long( 0 ) );
processSchedule.setSchedulerFrequency( ScheduleFrequencyEnum.ONE_TIME_ONLY.getScheduleFrequency() );
scheduleProcess( mailing, processSchedule, parameterValueMap, runByUserId );
return mailing;
}
catch( Exception e )
{
logger.error( "An error occured method saveAndScheduleMailing." + "For mailingId: " + mailing.getId() );
e.printStackTrace();
return null;
}
}
@SuppressWarnings( "rawtypes" )
private void scheduleProcess( Mailing mailing, ProcessSchedule processSchedule, LinkedHashMap parameterValueMap, Long runByUserId )
{
try
{
JobKey jobKey = buildJobKey( mailing.getId() );
JobDataMap triggerJobDataMap = new JobDataMap();
triggerJobDataMap.put( RUN_BY_USER_ID_PARAM_NAME, runByUserId.toString() );
triggerJobDataMap.put( MAILING_ID, mailing.getId() );
JobDetail job = JobBuilder.newJob( QuartzEmailProcess.class ).withIdentity( jobKey ).storeDurably().setJobData( triggerJobDataMap ).build();
// Define Trigger Instance
String triggerGroupName = buildTriggerGroupName( mailing.getId() );
String triggerName = buildTriggerName(mailing.getId());
Trigger trigger = QuartzProcessUtil.buildTrigger( processSchedule, job, triggerName, triggerGroupName );
Scheduler scheduler = factoryBean.getScheduler();
scheduler.addJob( job, true );
scheduler.scheduleJob( trigger );
}
catch( SchedulerException e )
{
e.printStackTrace();
}
}
//从Scheduler调用的实际服务:
@Service
@Transactional
public class QuartzEmailProcess extends QuartzJobBean
{
@Autowired
EmailService emailService;
private static final Logger logger = LoggerFactory.getLogger( QuartzEmailProcess.class );
protected void executeInternal( JobExecutionContext context ) throws JobExecutionException
{
try
{
Scheduler scheduler = context.getScheduler();
JobDetail jobDetail = context.getJobDetail();
Long mailingId = Long.valueOf( jobDetail.getJobDataMap().get( "MailingId" ).toString() );
emailService.sendMessage( mailingId );
}
catch( SchedulerException e )
{
e.printStackTrace();
}
}
与数据库交互的电子邮件服务类:所有类文件也在同一个项目和相同的包中。
public void sendMessage( Long mailingId )
{
Mailing mailing = mailingDao.getByMailingId( mailingId ); --> Getting Mailing object from DB
EmailHeaderRequest header = buildEmailHeaderFromMailingId( mailing );
for ( MailingRecipient recipient : mailing.getMailingRecipient() )
{
if ( recipient.getMailingRecipientType().equalsIgnoreCase( TO_VALUE ) && !StringUtils.isEmpty( recipient.getRecipient().getParticipant().getPrimaryEmailId() ) )
{
header.getRecipientEmails().clear();
header.getRecipientEmails().put( recipient.getUserId(), recipient.getRecipient().getParticipant().getPrimaryEmailId() );
EmailBodyRequest body = buildEmailBody( mailing.getTextCmKey(), recipient, true );
processEmail( header, body );
}
}
updateMailingStatus(mailing);
}
private String getUserEmailAddress( Long sender )
{
ApplicationUser user = userDao.findById( sender ); --> Getting user Object from DB
Iterator<UserRole> roleIterator = user.getUserRoles().iterator(); ---------------> GETTING LAZY INITIALIZATION EXCEPTION HERE ERROR
String emailAddress = null;
while(roleIterator.hasNext())
{
UserRole role = roleIterator.next();
if ( role.getRole().getRoleCode().equalsIgnoreCase( HCCoreConstants.PAX_VALUE ) )
{
emailAddress = user.getParticipant().getPrimaryEmailId();
break;
}
else if ( role.getRole().getRoleCode().equalsIgnoreCase( HCCoreConstants.ADMIN_VALUE ) )
{
emailAddress = ldapQueryService.getByUserName( user.getUserName() ).iterator().next();
break;
}
}
return emailAddress;
}
但我还是得到了这个问题。我尝试将事务管理器添加到调度程序,但没有解决问题
任何人都可以帮助我
更新1 - StackTrace
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.domain.ApplicationUser.userRoles, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:554)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:142)
at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:180)
at com.email.EmailService.getUserEmailAddress(EmailService.java:152)
at com.email.EmailService.buildEmailHeaderFromMailingId(EmailService.java:207)
at com.email.EmailService.sendMessage(EmailService.java:78)
at com.email.EmailService$$FastClassBySpringCGLIB$$66ae4112.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:649)
at com.EmailService$$EnhancerBySpringCGLIB$$ed23dcaf.sendMessage(<generated>)
at com.process.QuartzEmailProcess.executeInternal(QuartzEmailProcess.java:48)
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:75)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
答案 0 :(得分:1)
我能够通过更改SchedulerFactoryBean来解决问题
@Autowired
HCJobFactory jobFactory;
@Autowired
DataSource dataSource;
@Autowired
ApplicationContext applicationContext;
@Override
public void afterPropertiesSet() throws Exception
{
setJobFactory( jobFactory.getJobFactory() );
setApplicationContext(applicationContext);
setDataSource( dataSource );
//setTransactionManager( transactionManager );
super.afterPropertiesSet();
}