Java 从Grails控制器启动的新线程的Hibernate会话问题

Java 从Grails控制器启动的新线程的Hibernate会话问题,java,spring,multithreading,hibernate,grails,Java,Spring,Multithreading,Hibernate,Grails,我有一个运行良好的Grails2.2.4项目。最近我遇到了一个问题。该应用程序打印一份报告,并以PDF格式下载。客户在DB中有大量记录用于该报告,因此生成该报告需要花费大量时间。因此,我需要将其添加为一个新线程,以便在后台运行并生成报告并将其发送给用户 因此,我创建了一个新类,该类实现Runnable并调用从controller调用的相同服务 public class JasperReportProcessor implements Runnable { private static fi

我有一个运行良好的Grails2.2.4项目。最近我遇到了一个问题。该应用程序打印一份报告,并以PDF格式下载。客户在DB中有大量记录用于该报告,因此生成该报告需要花费大量时间。因此,我需要将其添加为一个新线程,以便在后台运行并生成报告并将其发送给用户

因此,我创建了一个新类,该类实现Runnable并调用从controller调用的相同服务

public class JasperReportProcessor implements Runnable {

  private static final Logger LOG =     LoggerFactory.getLogger(JasperReportProcessor.class);

  private ReportProcessor reportProcessor;
  private Parties party;
  private String bObject;
  private String contextUrl;
  private String shipmentIds;
  private Map<String, String> parameters;
  private Locale locale;


  public JasperReportProcessor() {}

  public JasperReportProcessor(final ReportProcessor reportProcessor, final Parties party,
      final String bObject, final String contextUrl, final String     shipmentIds, final Map<String, String> parameters) {
    this.reportProcessor = reportProcessor;
    this.party = party;
    this.bObject = bObject;
    this.contextUrl = contextUrl;
    this.shipmentIds = shipmentIds;
    this.parameters = parameters;
    this.locale = locale;
  }

  @Override
  public void run() {
    SessionFactory sessionFactory = DataSQLSupport.getSessionFactory();
    Session currentSession = null;
    Transaction tx =null;
    try {
      currentSession = sessionFactory.openSession();
      tx = currentSession.beginTransaction();
      LOG.info("THREAD STARTED for REPORT....................");
      //Below code was earlier called directly from Controller.
      Object[] reportData = this.reportProcessor.process(this.party,     this.bObject, this.contextUrl, this.shipmentIds, this.parameters,     this.locale);
      LOG.info("REPORT generated....{}", reportData[0]);
      LOG.info("THREAD ENDED...........");
      tx.commit();
    } catch (Exception ex) {
      LOG.error("OMG ERROR in THREAD....", ex);
      tx.rollback();
    } finally {
      currentSession.flush();
      currentSession.close();
    }

  }

}
@Component
class DataSQLSupport{
private static SESSION_FACTORY;

public DataSQLSupport() {}

@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
  SESSION_FACTORY = sessionFactory;
}

public static SessionFactory getSessionFactory(){
  return SESSION_FACTORY;
}

public static List<Object[]> getDataList(final String dataQuery) {
    Session currentSession = SESSION_FACTORY.getCurrentSession();
    Query query = currentSession.createSQLQuery(dataQuery);
    return (List<Object[]>) query.list();
}
}
我已尝试在datasource.groovy中添加以下内容

hibernate.current_session_context_class = 'thread'
我还尝试从服务而不是控制器调用线程,但也没有成功。我还打开了线程中的事务

我已经搜索了解决方案,但主要是配置问题。但由于我的项目在从控制器直接调用报表生成服务时正常工作,因此只有在创建新线程时才会出现问题。所以这似乎不是配置问题

我还添加了在新线程中创建新会话的代码,但这似乎不起作用

另外,问题只在于src/java类代码(我在上面添加了)。来自新线程的其他服务中的DB交互工作正常。该问题仅与getCurrentSession有关。openSession在grails的src.java类中工作得非常好。


请提出可能的问题。

以下是我在异步处理线程池中根据Quartz插件的功能进行会话的步骤:

// Inject persistence interceptor
PersistenceContextInterceptor persistenceInterceptor

void myMethod() {
    persistenceInterceptor.init()

    // insert code here. Transactions are handled by service classes.

    persistenceInterceptor.flush()
    persistenceInterceptor.clear()
    persistenceInterceptor.destroy()
}

我希望这能对您有所帮助。

以下是我在异步处理线程池中根据Quartz插件的功能进行会话的步骤:

// Inject persistence interceptor
PersistenceContextInterceptor persistenceInterceptor

void myMethod() {
    persistenceInterceptor.init()

    // insert code here. Transactions are handled by service classes.

    persistenceInterceptor.flush()
    persistenceInterceptor.clear()
    persistenceInterceptor.destroy()
}
我希望这对你有帮助

// Inject persistence interceptor
PersistenceContextInterceptor persistenceInterceptor

void myMethod() {
    persistenceInterceptor.init()

    // insert code here. Transactions are handled by service classes.

    persistenceInterceptor.flush()
    persistenceInterceptor.clear()
    persistenceInterceptor.destroy()
}