重建索引

 

使用hibernate search后,就会在加载hibernate配置文件时,自动在本地磁盘里建立索引文件,这个只是一个没有将数据库的记录加入到索引文件里去的,而只有一些必要信息的索引文件,因此,当我们将一个原来存在的索引文件删除后,想将它重建起来,那可以使用如下的方式来重建:

 

1 在重建的过程中,首先我遇到的问题是如何在使用注解的工程里面获取sessionFactory,这个使用另外加载配置文件的方式再实例化一个spring容器也是可以的,不过,这个spring容器产生的bean实例只是用到sessionFactory,而产生大量的bean实例,这若不用单例模式则很容易出现内在溢出的情况。

 

后来才知道,使用下面的方式可以获取sessionFactory(开始时我使用@Resource放在AnnotationSessionFactoryBean sessionFactory上面来加载它,是不对的)

 

@Autowired
	private ApplicationContext ctx;//用它来获取上下文,其实就相当于加载了spring配置文件一样
	
	private LocalSessionFactoryBean sessionFactory  = (LocalSessionFactoryBean) ctx.getBean("&sessionFactory");//用它来获取sessionFactory就可以成功啦

 

 

获取sessionFactory的目的是为了从配置文件里读出所有的mapping对象,再进行索引文件的重建,而不用写死在代码里指明那个类要重建索引,不然当你加入一个需索引的类,而忘记在这里改,那重建里就会没有它的信息,所以这里用配置文件里的mapping对象来处理重建的问题比较好。

 

2 逐一加对每一个类进行加入索引操作

 

3 重建前要先删除索引,删除时一个没有加入索引文件的类时会发生异常,这个要处理好。

 

具体实现如下:

 

 

//重建索引
	public void rebuildIndex() throws Exception{
		Session session = getSession();  
        
        FullTextSession fullTextSession = Search.getFullTextSession( session);  
        fullTextSession.setFlushMode(FlushMode.MANUAL);  
        fullTextSession.setCacheMode(CacheMode.IGNORE);  
//        Transaction tx = fullTextSession.beginTransaction();  //这里是配置了事务交由spring管理,会自动开启与提交,所以这里就没开启它来
  
//        WebApplicationContext cxt =   
//            WebApplicationContextUtils.getWebApplicationContext( getServletContext());  
//        AnnotationSessionFactoryBean factory = (AnnotationSessionFactoryBean) cxt.getBean( "&sessionFactory");  
        
        sessionFactory = (LocalSessionFactoryBean) ctx.getBean("&sessionFactory");
        
        if(sessionFactory != null){
            log.debug("sessionFactory成功从配置文件里注入");
        }
        else {
			log.debug("sessionFactory未从配置文件里注入,它为空,重建索引操作失败!");
			throw new Exception("sessionFactory未从配置文件里注入,它为空,重建索引操作失败!");
		}
        
        Iterator iter = sessionFactory.getConfiguration().getClassMappings();  
        while( iter.hasNext()) {//找出配置文件里写的持久化到数据库去的实体类
            RootClass clz = (RootClass) iter.next();  
            buildClassIndex( fullTextSession, clz.getMappedClass());  
        }  
  
//        tx.commit(); //index are written at commit time   
	}
private void buildClassIndex(FullTextSession fullTextSession, Class mappedClass) {
		//Scrollable results will avoid loading too many objects in memory
		try {
			fullTextSession.purgeAll( mappedClass);//删除索引
		} catch (Exception e) {//小心要处理一些没有加入索引文件的实体而引起的异常
			log.error("删除" + mappedClass + "索引的时候发生异常!可能该类没有加入索引文件。 ");
			return ;
		}
		int BATCH_SIZE = 100;
		ScrollableResults results = fullTextSession.createCriteria( mappedClass)
		    .setFetchSize(BATCH_SIZE).scroll( ScrollMode.FORWARD_ONLY );
		int index = 0;
		Object temp;
		while( results.next() ) {//这个是用来遍历一个类的所有记录的,我们可以用调试的方式查看每一个results.next值,它就是每一个封装的对象
		    index++;
		    temp = results.get(0);
		    fullTextSession.index(temp); //index each element
		    if (index % BATCH_SIZE == 0) {//达到多少条记录就将它写入磁盘中,那个100是我随便设置的
		        fullTextSession.flush(); //apply changes to indexes
		        fullTextSession.clear(); //clear since the queue is processed
		    }
		}
		if(index % BATCH_SIZE != 0){//确保它们都写出到磁盘,如果是自己开启一个事务来操作的话,我们不用下面的方法,那么只有等到事务提交后,索引文件才被更新
			fullTextSession.flush(); //apply changes to indexes
	        fullTextSession.clear(); //clear since the queue is processed
		}
	}
另外有关重建索引的还可以参考:
http://simonlei.iteye.com/blog/577068
http://jiangnan2112.iteye.com/blog/777917
http://isoloist.iteye.com/blog/856888

你可能感兴趣的:(spring,Hibernate,bean,Blog,配置管理)