Pergunta

Eu estou tentando chamar o método baseado em algum intervalo de tempo, aqui estão alguns grãos dentro 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>

Aqui está o método que eu estou tentando chamar:

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

Aqui está a mensagem de exceção que eu recebo:

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

Eu passei tempo pesquisando um monte, até agora, também eu tentei modificar meu método como este:

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

E eu fico diferente msg de erro, eu recebo: Invocation of method 'findItemByPIdEndDate' on target class [class com.management.engine.Implementation] failed; nested exception is could not execute query], ninguém sabe o que é isso tudo, alguma sugestão? obrigado

Também a minha 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>
Foi útil?

Solução

Para o segundo erro ( "Não foi possível executar a consulta"), eu não sei e estou realmente querendo saber o que os olhares sessão como.

Na ação, AFAIK, o contexto persistente não está disponível para Quartz Jobs como nada cuidar de estabelecer uma sessão de Hibernate para eles (Quartz é executado fora do contexto de Servlets e a sessão aberta no modo padrão não se aplica aqui). É por isso que você recebe o primeiro erro ( "Nenhuma sessão de hibernação obrigado a thread").

Uma solução para isso é descrito em AOP - Spring - Hibernate Sessões de threads em segundo plano / empregos . Neste post, mostra o autor como você pode usar proxies Primavera AOP para ligar um interceptor de hibernação que lhe dá acesso ao contexto de persistência e cuida de fechar e abrir as sessões para você .

não testá-lo me embora, mas ele deve funcionar.

Outras dicas

eu também estava enfrentando o mesmo " HibernateException: Não Hibernate Session obrigado a enfiar " exceção

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)

e eu resolvi-lo seguindo o exemplo aqui .

código relevante

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

configuração de feijão Relevante dentro 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>

Há primavera bug https://jira.spring.io/browse/SPR-9020 E não há solução alternativa. Configurar sessão com propriedade hibernate.current_session_context_class com esta classe: https://gist.github.com/seykron/4770724

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top