Hibernate Sessionfactory重启|弹簧 [英] Hibernate Sessionfactory restart | Spring

查看:88
本文介绍了Hibernate Sessionfactory重启|弹簧的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的要求如下:

我需要在我的Spring Web应用程序中重新启动(或重建)hibernate会话工厂,并使用新获得的HBM文件来自外部。



目前我的Sessionfactory类如下,使用SessionFactory代理拦截'OpenSession'调用。



我正在检查一个条件来重新启动并重建sessionFactory。



我的问题是,在并发环境中,处于其他事务中间的其他用户正在受到影响

有没有办法通过检查所有事务并打开会话来执行重新启动,并在所有其他完成后执行重建会话工厂?



或任何其他解决方案。



代码:

  public class DataStoreSessionFactory extends LocalSessionFactoryBean 
{


private boolean restartFactory = false;



@Override
保护void postProcessConfiguration(配置配置)抛出HibernateException
{
super.postProcessConfiguration(config);
updateHBMList(config);


$ b $ private void updateHBMList(final Configuration config)
{

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

@Override
public SessionFactory getObject()
{

Object obj = super.getObject();
$ b $ * b $ b *代理的调用处理程序
* /
SessionFactoryProxy proxy = new SessionFactoryProxy(this,(SessionFactory)obj);
$ b / **
*在返回的会话工厂对象上调用的所有方法都将通过此代理的调用
*处理程序
* /
SessionFactory sessionFactory =(SessionFactory)Proxy.newProxyInstance(getClass()。getClassLoader(),
new Class [] {SessionFactory.class},
proxy);
return sessionFactory;
}

静态类SessionFactoryProxy实现InvocationHandler
{


private SessionFactory sessionFactory;

private LocalSessionFactoryBean factoryBean;

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

$ b $ public Object invoke(Object method,Method method,Object [] args)throws Throwable
{
/ **
*仅当调用的方法是openSession - 检查会话工厂是否应该重新启动,然后只有
*调用请求的方法
* /
if(method.getName()。equals(openSession)) )
{
restartSessionFactoryIfNecessary();
}
return method.invoke(sessionFactory,args);


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



private synchronized void restartSessionFactory()
{
log.info(Restarting session ...);
factoryBean.destroy();
尝试
{
factoryBean.afterPropertiesSet();
sessionFactory = factoryBean.getObject();

catch(Exception e)
{
log.error(重启会话时出错:+ e.getMessage());
抛出新的RuntimeException(e);



$ / code $ / pre

感谢
Appasamy

解决方案

您可以关注SessionFactoryUtils以确定事务是否发生在Session工厂中,然后决定重新启动会话工厂或not:
您需要在您的文件中导入 - > org.springframework.orm.hibernate.SessionFactoryUtils,并使用以下API。

  static boolean hasTransactionalSession(SessionFactory sessionFactory); 

上面的API返回当前线程是否存在事务性Hibernate Session,即Session绑定到Spring的事务工具当前线程。另外还有一个API,以防万一您需要检查会话工厂中的会话是否是事务性的:

 静态布尔isSessionTransactional(Session session,SessionFactory sessionFactory); 

上面的API返回给定的特定Hibernate Session是否是事务性的,也就是说,绑定到当前线程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.

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

解决方案

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.

这篇关于Hibernate Sessionfactory重启|弹簧的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆