简体   繁体   English

Hibernate Sessionfactory重新启动| 弹簧

[英]Hibernate Sessionfactory restart | Spring

My requirement is as follows: 我的要求如下:

I need to restart(or rebuild) hibernate session factory in my Spring web application at frequent intervals with the new HBM files I get from outside. 我需要使用从外部获得的新HBM文件,频繁地重新启动(或重建)Spring Web应用程序中的休眠会话工厂。

Currently my Sessionfactory class is as follows with a SessionFactory Proxy to intercept 'OpenSession' call. 当前,我的Sessionfactory类如下所示,它带有一个SessionFactory代理来拦截“ OpenSession”调用。

There I am checking for a condition to restart and rebuilding sessionFactory. 在那里,我正在检查重新启动和重建sessionFactory的条件。

My problem here is , in concurrent environment the other users who are in middle of other transaction is getting affected during this restart. 我的问题是,在并发环境中,处于其他事务中间的其他用户在此重新启动期间会受到影响。

Is there anyway to carryout the restart by checking all the transactions and open sessions and carry out rebuilding session factory once all other completes? 无论如何,是否要通过检查所有事务和打开的会话来执行重新启动,并在其他所有操作完成后执行重建会话工厂?

or any other solution exists. 或存在任何其他解决方案。

Code: 码:

public class DataStoreSessionFactory extends LocalSessionFactoryBean
{


   private boolean restartFactory = false;



   @Override
   protected void postProcessConfiguration(Configuration config) throws HibernateException
   {
      super.postProcessConfiguration(config);
      updateHBMList(config);
   }


   private void updateHBMList(final Configuration config)
   {

      config.addXML(modelRegistry.generateMapping());
   }

   @Override
   public SessionFactory getObject()
   {

      Object obj = super.getObject();

      /*
       * Invocation handler for the proxy
       */
      SessionFactoryProxy proxy = new SessionFactoryProxy(this, (SessionFactory) obj);

      /**
       * All the methods invoked on the returned session factory object will pass through this proxy's invocation
       * handler
       */
      SessionFactory sessionFactory = (SessionFactory) Proxy.newProxyInstance(getClass().getClassLoader(),
                                                                              new Class[] { SessionFactory.class },
                                                                              proxy);
      return sessionFactory;
   }

   static class SessionFactoryProxy implements InvocationHandler
   {


      private SessionFactory sessionFactory;

      private LocalSessionFactoryBean factoryBean;

      public SessionFactoryProxy(LocalSessionFactoryBean factoryBean, SessionFactory sessionFactory)
      {
         this.factoryBean = factoryBean;
         this.sessionFactory = sessionFactory;
      }

      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
      {
         /**
          * Only if the method invoked is openSession - check if the session factory should be restarted, and only then
          * invoke the requested method
          */
         if (method.getName().equals("openSession"))
         {
            restartSessionFactoryIfNecessary();
         }
         return method.invoke(sessionFactory, args);
      }

      private void restartSessionFactoryIfNecessary()
      {
         restartSessionFactory();
         /*if (((DataStoreSessionFactory) factoryBean).isRestartFactory())
         {
            restartSessionFactory();
         }*/
      }

      private synchronized void restartSessionFactory()
      {
         log.info("Restarting session...");
         factoryBean.destroy();
         try
         {
            factoryBean.afterPropertiesSet();
            sessionFactory = factoryBean.getObject();
         }
         catch (Exception e)
         {
            log.error("Error while restarting session: " + e.getMessage());
            throw new RuntimeException(e);
         }
      }
   }

Thanks, Appasamy 谢谢,Appasamy

You can following SessionFactoryUtils to determine whether a transaction is taking place in Session factory and then decide to restart the session factory or not: You will need to import--> org.springframework.orm.hibernate.SessionFactoryUtils in you file, and use the following API. 您可以遵循SessionFactoryUtils来确定是否在会话工厂中进行事务,然后决定是否重新启动会话工厂:您需要在文件中导入-> org.springframework.orm.hibernate.SessionFactoryUtils,并使用以下API。

    static boolean  hasTransactionalSession(SessionFactory sessionFactory); 

Above API returns whether there is a transactional Hibernate Session for the current thread, that is, a Session bound to the current thread by Spring's transaction facilities.There is also another API just in case if you need to check if a session is transactional in session factory currently: 上面的API返回当前线程是否有事务性的Hibernate会话,即由Spring的事务处理工具绑定到当前线程的会话。还有另一个API,以防万一您需要检查会话是否在会话中是事务性的目前工厂:

static boolean isSessionTransactional(Session session,SessionFactory sessionFactory);

Above API returns whether the given particular Hibernate Session is transactional, that is, bound to the current thread by Spring's transaction facilities. 上面的API返回给定的特定Hibernate会话是否是事务性的,即由Spring的事务功能绑定到当前线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM