讨论一下hibernate如何动态注册一个动态生成的实体类

  如何动态生成实体类请参考这篇博文:http://www.cnblogs.com/anai/p/4269858.html

  下面说说得到实体类后,如何能使用hibernate的接口来进行数据访问。

  我们都知道,hibernate是在web容器启动的时候根据相关配置信息,扫描class文件,然后注册到SessionFactory中。通过getAllClassMetadata()可以得到已经注册过的实体类的元信息。那么如果是在容器启动已经完成后,程序正常运行期间产生的类,显然是不能直接使用hibernate的接口的,因为hibernate还不认识这个新创建的类呢。那么如何在这个阶段让它们认识并建立关系呢,思路很简单,就是注册呗,但是这里有个问题,我们不能使用原来的sessionFactory了,会导致事务安全的问题,而且hibernate也建议sessionFactory一旦创建好了,就不要对其做修改,所以即使configration的内容变化了,之前就创建好的sessionFactory也不会受到影响。好了下面上代码:

代码中 SpringContextUtil.getBean("&sessionFactory") 的&符的含义,可以参考这篇博文:http://www.cnblogs.com/anai/p/4258934.html

public class myDao{   
    @Autowired
    @Qualifier("sessionFactory")
    private SessionFactory sessionFactory;

    private List<SessionFactory> sessionFactoryList = new ArrayList<SessionFactory>();

    /******************** 以下 方法只适用于对象是动态加载进JVM的情况******************************/
    /**
     * 获取Session工厂
     * 如果指定的model是动态加载到JVM中的,
     * 那么就更新当前的configuration,
     * 并重新创建一个Session工厂(因为Session工厂是全局单例的,所以创建好之后最好不要改动,容易出现事务安全问题),
     * 以便能为该对象执行数据库访问操作
     * 该方法如果频繁使用,会增加系统开销
     * @param entityClass
     * @return
     */
    private SessionFactory obtainSessionFactory(Class<?> entityClass){
        Map<String,ClassMetadata> map = sessionFactory.getAllClassMetadata();
        Set<String> set = map.keySet();
        if(!set.contains(entityClass.getName())){
            for(SessionFactory factory : sessionFactoryList){
                Set<String> existSet = factory.getAllClassMetadata().keySet();
                if(existSet.contains(entityClass.getName())){//该sessionFactory包含了此实体,就用该SessionFactory
                    return factory;
                }
            }
            LocalSessionFactoryBean localSessionFactoryBean = SpringContextUtil.getBean("&sessionFactory");
            Configuration configuration = localSessionFactoryBean.getConfiguration();
            synchronized(configuration){//避免并发操作导致configuration重复添加相同的entityClass
                if(configuration.getClassMapping(entityClass.getName())==null){
                    configuration.addAnnotatedClass(entityClass);
                }
            }
            ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
            SessionFactory newSessionFactory = configuration.buildSessionFactory(serviceRegistry);
            sessionFactoryList.add(newSessionFactory);
            return newSessionFactory;
        }else{
            return sessionFactory;
        }
    }
}

 

posted @ 2015-02-03 15:57  程序员一一涤生  阅读(4079)  评论(1编辑  收藏  举报