Hibernate Sessionfactory restart | Spring

廉价感情. 提交于 2019-12-07 07:37:24

问题


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.

Currently my Sessionfactory class is as follows with a SessionFactory Proxy to intercept 'OpenSession' call.

There I am checking for a condition to restart and rebuilding 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


回答1:


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.

    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:

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.



来源:https://stackoverflow.com/questions/13987720/hibernate-sessionfactory-restart-spring

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!