4

私の要件は次のとおりです。

外部から取得した新しいHBMファイルを使用して、Spring WebアプリケーションでHibernateセッションファクトリを頻繁に再起動(または再構築)する必要があります。

現在、私のSessionfactoryクラスは、「OpenSession」呼び出しをインターセプトするSessionFactoryプロキシを使用して次のようになっています。

そこで、sessionFactoryを再起動して再構築するための条件をチェックしています。

ここでの私の問題は、並行環境では、他のトランザクションの途中にいる他のユーザーがこの再起動中に影響を受けることです。

すべてのトランザクションと開いているセッションをチェックして再起動を実行し、他のすべてが完了したらセッションファクトリの再構築を実行する方法はありますか?

または他の解決策が存在します。

コード:

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

ありがとう、Appasamy

4

1 に答える 1

2

SessionFactoryUtilsをフォローして、トランザクションがセッションファクトリで行われているかどうかを判断し、セッションファクトリを再起動するかどうかを決定できます。ファイルにインポート-> org.springframework.orm.hibernate.SessionFactoryUtilsを入力し、次のAPI。

    static boolean  hasTransactionalSession(SessionFactory sessionFactory); 

上記のAPIは、現在のスレッドのトランザクションHibernateセッション、つまり、Springのトランザクション機能によって現在のスレッドにバインドされたセッションがあるかどうかを返します。セッションがセッションでトランザクションであるかどうかを確認する必要がある場合に備えて、別のAPIもあります。現在の工場:

static boolean isSessionTransactional(Session session,SessionFactory sessionFactory);

上記のAPIは、指定された特定のHibernateセッションがトランザクションであるかどうか、つまり、Springのトランザクション機能によって現在のスレッドにバインドされているかどうかを返します。

于 2012-12-21T10:00:25.800 に答える