2009-10-23 96 views
3

我想基于一些间隔时间调用方法,这里是内部的applicationContext.xml问题与春天石英

<bean id="MngtTarget" 
    class="com.management.engine.Implementation" 
    abstract="false" lazy-init="true" autowire="default" dependency-check="default"> 

    <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> 
     <property name="targetObject" ref="MngtTarget" /> 
     <property name="targetMethod" value="findItemByPIdEndDate"/> 
    </bean> 


    <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> 

     <property name="jobDetail" ref="jobDetail" /> 
     <!-- 10 seconds --> 
     <property name="startDelay" value="10000" /> 
     <!-- repeat every 50 seconds --> 
     <property name="repeatInterval" value="20000" /> 
    </bean> 


    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 
     <property name="triggers"> 
      <list> 
       <ref bean="simpleTrigger" /> 
      </list> 
     </property> 
    </bean> 

这里是一些豆子是我想调用的方法:

public List<Long> I need findItemByPIdEndDate() throws Exception { 

       List<Long> list = null; 

       try{ 
         Session session = sessionFactory.getCurrentSession(); 

         Query query = session.getNamedQuery("endDateChecker"); 
         list = query.list(); 

         for(int i=0; i<list.size(); i++) 
         { 
           System.out.println(list.get(i)); 
         } 

         System.out.println("Total " + list.size()); 

       }catch (HibernateException e){ 
         throw new DataAccessException(e.getMessage()); 
       } 

       return list; 
     } 

这里是异常消息,我得到:

Invocation of method 'findItemByPIdEndDate' on target class [class com.management.engine.Implementation] failed; nested exception is No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here 

我花的时间很多谷歌上搜索,到目前为止还我已经特里d修改我的方法是这样的:

public List<Long> I need findItemByPIdEndDate() throws Exception { 

        List<Long> list = null; 

        try{ 
          Session session = sessionFactory.openSession(); 

          Query query = session.getNamedQuery("endDateChecker"); 
          list = query.list(); 

          for(int i=0; i<list.size(); i++) 
          { 
            System.out.println(list.get(i)); 
          } 

          System.out.println("Total " + list.size()); 
          session.close(); 
        }catch (HibernateException e){ 
          throw new DataAccessException(e.getMessage()); 
        } 

        return list; 
      } 

我得到不同的错误味精,我得到:Invocation of method 'findItemByPIdEndDate' on target class [class com.management.engine.Implementation] failed; nested exception is could not execute query],任何人都知道这是什么一回事,有什么建议?谢谢

而且我queries.hbm.xml

<hibernate-mapping> 

<sql-query name="endDateChecker"> 
<return-scalar column="PId" type="java.lang.Long"/> 
     <![CDATA[select 
    item_pid as PId 
    from 
     item 
     where 
     end_date < trunc(sysdate)]]>  
</sql-query> 
</hibernate-mapping> 
+0

请添加Hibernate配置 – sfussenegger 2009-10-23 14:00:36

+0

就打印*查询*对象,看看你是否得到预期的查询''endDateChecker'' – 2009-10-23 14:20:26

+0

我越来越期待查询 – ant 2009-10-23 14:33:30

回答

5

对于第二个错误(“无法执行查询”),我不知道,我真的很疑惑会议的样子。在Quarted Jobs中,持久化上下文对于为它们建立一个Hibernate Session没有任何帮助(Quartz在Servlets的上下文之外运行,而view view中的开放式会话在这里不适用),在这个契约中,AFAIK没有提供持久化上下文。 。这就是为什么你得到第一个错误(“没有hibernate会话绑定到线程”)。

对此的一种解决方案在AOP – Spring – Hibernate Sessions for background threads/jobs中描述。在这篇文章中,作者展示了如何使用Spring AOP代理连接一个hibernate拦截器,该拦截器允许您访问持久化上下文,并且需要关闭并打开您的会话

虽然没有自己测试,但它应该工作。

+0

谢谢m8,这不是解决方案,但它使我成为一个,因此它有资格成为正确的答案。 gr8 – ant 2009-10-26 13:39:05

+0

我很高兴能提供帮助。但是,您能否详细说明“这不是解决方案”,以便我可以更新此答案?提前致谢。 – 2009-10-26 14:18:10

3

我也正面临着同样的“HibernateException的:没有Hibernate的Session绑定到线程”异常

2012-01-13 13:16:15.005 DEBUG MyQuartzJob Caught an exception 
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here 
at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:63) 
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:687) 
at com.company.somemodule.dao.hibernate.AbstractHibernateDaoImpl.getSession(AbstractHibernateDaoImpl.java:107) 
at com.company.somemodule.dao.hibernate.SomeDataDaoImpl.retrieveSomeData(SomeDataDaoImpl.java:264) 

,我遵循的例子here解决它。

相关代码

import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.quartz.JobExecutionContext; 
import org.quartz.JobExecutionException; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.orm.hibernate3.SessionFactoryUtils; 
import org.springframework.orm.hibernate3.SessionHolder; 
import org.springframework.scheduling.quartz.QuartzJobBean; 
import org.springframework.transaction.support.TransactionSynchronizationManager; 

import com.company.somemodule.dao.SomeDataDao; 
import com.company.somemodule.SomeData; 

public class MyQuartzJob extends QuartzJobBean implements Runnable { 

    private boolean existingTransaction; 
    private JobExecutionContext jobExecCtx; 
    private static Logger logger = LoggerFactory.getLogger(MyQuartzJob.class); 
    private SomeDataDao someDataDao; //set by Spring 
    private Session session; 
    private SessionFactory hibernateSessionFactory; //set by Spring 

    protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException 
    this.jobExecCtx = ctx; 
    run(); 
    } 

    private void handleHibernateTransactionIntricacies() { 
    session = SessionFactoryUtils.getSession(hibernateSessionFactory, true); 
    existingTransaction = SessionFactoryUtils.isSessionTransactional(session, hibernateSessionFactory); 
    if (existingTransaction) { 
     logger.debug("Found thread-bound Session for Quartz job"); 
    } else { 
     TransactionSynchronizationManager.bindResource(hibernateSessionFactory, new SessionHolder(session)); 
    } 
    } 


    private void releaseHibernateSessionConditionally() { 
    if (existingTransaction) { 
     logger.debug("Not closing pre-bound Hibernate Session after TransactionalQuartzTask"); 
    } else { 
     TransactionSynchronizationManager.unbindResource(hibernateSessionFactory); 
     SessionFactoryUtils.releaseSession(session, hibernateSessionFactory); 
    } 
    } 

    @Override 
    public void run() { 
    // .. 

    // Do the required to avoid HibernateException: No Hibernate Session bound to thread 
    handleHibernateTransactionIntricacies(); 

    // Do the transactional operations 
    try { 

     // Do DAO related operations .. 

    } finally { 
     releaseHibernateSessionConditionally(); 
    } 
    } 

    public void setHibernateSessionFactory(SessionFactory hibernateSessionFactory) { 
    this.hibernateSessionFactory = hibernateSessionFactory; 
    } 

    public void setSomeDataDao(SomeDataDao someDataDao) { 
    this.someDataDao = someDataDao ; 
    } 
} 

相关bean中的applicationContext.xml

配置
<bean name="myJob" class="org.springframework.scheduling.quartz.JobDetailBean"> 
    <property name="jobClass" value="com.somecompany.worker.MyQuartzJob" /> 
    <property name="jobDataAsMap"> 
    <map> 
     <entry key="hibernateSessionFactory" value-ref="sessionFactory" /> 
     <entry key="someDataDao" value-ref="someDataDao" /> 
    </map> 
    </property> 
</bean> 
+0

你已经救了我的一天! – Reusable 2014-03-25 07:12:25