代码之家  ›  专栏  ›  技术社区  ›  ant

弹簧石英问题

  •  3
  • ant  · 技术社区  · 15 年前

    我正试图根据一些间隔时间调用方法,这里是applicationContext.xml中的一些bean

    <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
    

    到目前为止,我已经花了很多时间在谷歌上搜索了,我还尝试修改我的方法,如下所示:

     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] 有人知道这是怎么回事,有什么建议吗?谢谢您

    还有my 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>
    
    3 回复  |  直到 10 年前
        1
  •  5
  •   Pascal Thivent    15 年前

    对于第二个错误(“无法执行查询”),我不知道,我真的很想知道会话是什么样子的。

    事实上,Afaik对于Quartz作业来说,持久上下文是不可用的,因为不需要为它们建立休眠会话(Quartz在servlet上下文之外运行,而视图模式中的开放会话在这里不适用)。这就是为什么会出现第一个错误(“没有绑定到线程的休眠会话”)。

    其中一个解决方案在 AOP – Spring – Hibernate Sessions for background threads / jobs . 在这篇文章中,作者展示了 如何使用SpringAOP代理来连接一个Hibernate拦截器,该拦截器允许您访问持久性上下文,它负责为您关闭和打开会话。 .

    虽然我自己没有测试过,但应该可以。

        2
  •  3
  •   user799188    13 年前

    我也面临同样的情况” HibernateException:没有绑定到线程的休眠会话 “例外”

    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 ;
      }
    }
    

    applicationContext.xml中的相关bean配置

    <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>
    
        3
  •  0
  •   digz6666    10 年前

    有虫泉 https://jira.spring.io/browse/SPR-9020 还有解决办法。 使用hibernate配置会话。当前的会话上下文类属性: https://gist.github.com/seykron/4770724