ssh+compass实现收索

本文记录了使用Struts2、Hibernate、Spring与Compass集成的过程,重点介绍了在集成过程中遇到的常见问题及其解决方案,包括Spring与Hibernate的jar包冲突、对象注入失败等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

照着v512 刘伟老师做了一个ssh 集成compass 的小程序  最后的感觉是compass   很好很强大,我把我其中遇到的问题写出来,也许大家也会遇到,省下不必要的麻烦。 

 

我的类库是 struts2+ hibernate3.2+spring2.5+ compass2.1

 

第一个问题,也是让我最崩溃的问题

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'compassIndexBuilder' defined in ServletContext resource [/WEB-INF/applicationContext-compass.xml]: Cannot resolve reference to bean 'compassGps' while setting bean property 'compassGps'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'compassGps' defined in ServletContext resource [/WEB-INF/applicationContext-compass.xml]: Cannot resolve reference to bean 'compass' while setting bean property 'compass'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'compass' defined in ServletContext resource [/WEB-INF/applicationContext-compass.xml]: Cannot resolve reference to bean 'transactionManager' while setting bean property 'transactionManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.objectweb.asm.ClassVisitor.visit(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V


 

看到这么长的错,我首先感觉到的就是,自己的代码有问题,死劲的找没找到。在网上搜了一下发现原来这错挺常见,我就按别人的提示一个一个的试,最终在http://atao.iteye.com/blog/281282 找到了答案,是由于Spring中的“asm-2.2.3.jar”和Hibernate中的“asm.jar”包冲突。解决办法是移除Spring2.5 AOP Libraries中的“asm-2.2.3.jar”即可 。可是让我头痛的是怎么移除呢?MyEclipse 6.5 上要想单独移除asm-2.2.3 是不可能的,只能连spring 2.5 aop Libraries 一块移除,然后重新添加,这次选择直接添加.jar文件到lib 目录,但是我就怎么呀找到那个选择直接添加.jar文件的窗口选项在哪里,后来没办法只好在发布以后删除发布完成以后tomcat 对应目录下的asm-2.2.3.jar 。第一个问题就这样勉强的解决了。

 

第二个问题,

java.lang.IllegalArgumentException: Original must not be null

 有了这个问题,基本就能确定是spring 不能将对象注入的原因  一般是找不到对应的set 方法,我的错误是没写下面红颜色的set 方法。

package com.cntion.example.action;

import java.util.List;

import com.cntion.example.model.Product;
import com.cntion.example.service.ProductManager;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
/**
 * @author hsmiel
 *
 */
public class ProductAction extends ActionSupport {
	private ProductManager productManager;
	private Product product;
	private String queryString;
	
	public ProductManager getProductManager() {
		return productManager;
	}
	public void setProductManager(ProductManager productManager) {
		this.productManager = productManager;
	}
	public Product getProduct() {
		return product;
	}
	public void setProduct(Product product) {
		this.product = product;
	}
	public String getQueryString() {
		return queryString;
	}
	public void setQueryString(String queryString) {
		this.queryString = queryString;
	}
	
	
	

	public String insert(){
		productManager.insertProduct(product);
		return SUCCESS;
	}
	
	public String search(){
		List result=productManager.searchProduct(queryString);
		ServletActionContext.getRequest().setAttribute("searchresults",result);
		return SUCCESS;
	}




}

 

下面是我实现的关键代码 

 

1  每次启动自动生成索引  CompassIndexBuilder.java

package com.cntion.example.service.impl;

import org.compass.gps.CompassGps;
import org.springframework.beans.factory.InitializingBean;


/**
 * 通过quartz定时调度定时重建索引或自动随Spring ApplicationContext启动而重建索引的Builder.
 * 会启动后延时数秒新开线程调用compassGps.index()函数.
 * 默认会在Web应用每次启动时重建索引,可以设置buildIndex属性为false来禁止此功能.
 * 也可以不用本Builder, 编写手动调用compassGps.index()的代码.
 *
 */
public class CompassIndexBuilder implements InitializingBean {   
    // 是否需要建立索引,可被设置为false使本Builder失效.
    private boolean buildIndex = false;

    // 索引操作线程延时启动的时间,单位为秒
    private int lazyTime = 10;

    // Compass封装
    private CompassGps compassGps;

    // 索引线程
    private Thread indexThread = new Thread() {

        @Override
        public void run() {
            try {
                Thread.sleep(lazyTime * 1000);
                System.out.println("begin compass index...");
                long beginTime = System.currentTimeMillis();
                // 重建索引.
                // 如果compass实体中定义的索引文件已存在,索引过程中会建立临时索引,
                // 索引完成后再进行覆盖.
                compassGps.index();
                long costTime = System.currentTimeMillis() - beginTime;
                System.out.println("compss index finished.");
                System.out.println("costed " + costTime + " milliseconds");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };

    /**
     * 实现<code>InitializingBean</code>接口,在完成注入后调用启动索引线程.
     *
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     */
    public void afterPropertiesSet() throws Exception {
        if (buildIndex) {
            indexThread.setDaemon(true);
            indexThread.setName("Compass Indexer");
            indexThread.start();
        }
    }

    public void setBuildIndex(boolean buildIndex) {
        this.buildIndex = buildIndex;
    }

    public void setLazyTime(int lazyTime) {
        this.lazyTime = lazyTime;
    }

    public void setCompassGps(CompassGps compassGps) {
        this.compassGps = compassGps;
    }
}

 

 2  spring 配置文件 applicationContext.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" default-lazy-init="true">


	<!-- 定义数据源的Bean ,给Hibernate的sessionFactory-->
	<bean id="dataSource"
		class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName"
			value="oracle.jdbc.driver.OracleDriver">
		</property>
		<property name="url"
			value="jdbc:oracle:thin:@localhost:1521:hsmile">
		</property>
		<property name="username" value="scott"></property>
		<property name="password" value="tiger"></property>
	</bean>
	
<!-- 定义Hibernate的sessionFactory,通过该Bean,可以获得Hibernate的Session-->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.Oracle9Dialect
				</prop>
				<!--设置二级缓冲-->
				<prop key="hibernate.cache.provider_class">
					org.hibernate.cache.EhCacheProvider
				</prop>
				<!--设置二级缓冲,打开查询缓冲-->
				<prop key="hibernate.cache.use_query_cache">true</prop>
				<!--设置显示Hibernate操作的SQL语句-->
				<prop key="hibernate.show_sql">true</prop>
			</props>
		</property>
		<property name="mappingResources">
			<list>				
				<value>
					com/cntion/example/model/Product.hbm.xml
				</value>
			</list>
		</property>
	</bean>
	
	<!-- 注入依赖类  -->
	<bean id="productDao" class="com.cntion.example.dao.hibernate.ProductDaoHibernate">
	<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>
	
	<bean id="productManager" class="com.cntion.example.service.impl.ProductManagerImpl">
	<property name="productDao" ref="productDao"></property>
	<property name="compassTemplate" ref="compassTemplate"></property>
	</bean>
	
	<bean id="productBean" class="com.cntion.example.action.ProductAction" scope="prototype">
	<property name="productManager" ref="productManager"></property>
	</bean>
	
			<!-- 配置事务管理器 -->	
	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory">
			<ref local="sessionFactory"/>
		</property>
	</bean>
    
    <!-- 配置事务特性 ,配置add、delete和update开始的方法,事务传播特性为required-->       
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
    	<tx:attributes>
    		<tx:method name="insert*" propagation="REQUIRED"/>
    		<tx:method name="delete*" propagation="REQUIRED"/>
    		<tx:method name="update*" propagation="REQUIRED"/>
    		<tx:method name="*" read-only="true"/>
    	</tx:attributes>
    </tx:advice>
    
    <!-- 配置那些类的方法进行事务管理,当前cn.com.jobedu.oa.service包中的子包、类中所有方法需要,还需要参考tx:advice的设置 -->
    <aop:config>
    	<aop:pointcut id="allManagerMethod" expression="execution (* com.cntion.example.service.*.*(..))"/>
    	<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>
    </aop:config> 
</beans>

 

3   sprint 集成 compass 配置文件  applicationContext-compass.xml

 

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation=" http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
	default-lazy-init="true">


	<bean id="annotationConfiguration"
		class="org.compass.annotations.config.CompassAnnotationsConfiguration">
	</bean>

	<!-- org.compass.spring.LocalCompassBean -->
	<bean id="compass" class="org.compass.spring.LocalCompassBean">
		<property name="resourceDirectoryLocations">
			<list>
				<value>classpath:com/cntion</value>
			</list>
		</property>
		<property name="connection">
			<value>/lucene/indexes</value>
		</property>


		<property name="classMappings">
			<list>
				<value>com.cntion.example.model.Product</value>
			</list>
		</property>
		<property name="compassConfiguration"
			ref="annotationConfiguration" />

		<property name="compassSettings">
			<props>
				<prop key="compass.transaction.factory">
					org.compass.spring.transaction.SpringSyncTransactionFactory
				</prop>
				<prop
					key="compass.engine.analyzer.MMAnalyzer.CustomAnalyzer">
					net.paoding.analysis.analyzer.PaodingAnalyzer
				</prop>
			</props>
		</property>

		<property name="transactionManager" ref="transactionManager" />
	</bean>


	<bean id="hibernateGpsDevice"
		class="org.compass.gps.device.hibernate.HibernateGpsDevice">
		<property name="name">
			<value>hibernateDevice</value>
		</property>
		<property name="sessionFactory" ref="sessionFactory" />
		<property name="mirrorDataChanges">
			<value>true</value>
		</property>
	</bean>
	<!-- 同步更新索引 -->
	<bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps"
		init-method="start" destroy-method="stop">
		<property name="compass" ref="compass" />
		<property name="gpsDevices">
			<list>
				<bean
					class="org.compass.spring.device.SpringSyncTransactionGpsDeviceWrapper">
					<property name="gpsDevice" ref="hibernateGpsDevice" />
				</bean>
			</list>
		</property>
	</bean>


	<bean id="compassTemplate"
		class="org.compass.core.CompassTemplate">
		<property name="compass" ref="compass" />
	</bean>

	<!-- 定时重建索引(利用quartz)或随Spring ApplicationContext启动而重建索引 -->
	<bean id="compassIndexBuilder"
		class="com.cntion.example.service.impl.CompassIndexBuilder"
		lazy-init="false">
		<property name="compassGps" ref="compassGps" />
		<property name="buildIndex" value="true" />
		<property name="lazyTime" value="10" />
	</bean>

</beans>

 

4  struts.xml

 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
	<constant name="struts.objectFactory" value="spring" />

	<include file="struts-default.xml" />

	<package name="product" extends="struts-default"
		namespace="/product">
		<!-- 配置Struts2的Action,class值要与applicationContext*.xml中的id的值一致。 -->
		<action name="insert" class="productBean" method="insert">
			<result>insertOk.jsp</result>
		</action>
		<action name="search" class="productBean" method="search">
			<result>searchResults.jsp</result>
		</action>


	</package>

</struts>

 

5  收索方法  红颜色的地方是表示按照商品名称收索

	public List searchProduct(String queryString) {
		Compass compass=compassTemplate.getCompass();
		CompassSession session=compass.openSession();

		CompassHits hits=session.queryBuilder().queryString("name:"+queryString).toQuery().hits();
		List list=new ArrayList();
		
		for(int i=0;i<hits.length();i++){
			Product hit=(Product)hits.data(i);
			list.add(hit);
		}

		return list;
	}

 6  实体类

 

package com.cntion.example.model;
import org.compass.annotations.*;

/**
 * Product entity.
 * 
 * @author MyEclipse Persistence Tools
 */
@Searchable
public class Product implements java.io.Serializable {

	// Fields
	@SearchableId
	private String id;
	@SearchableProperty(name="name")
	private String name;
	@SearchableProperty(name="price")
	private Double price;
	@SearchableProperty(name="brand")
	private String brand;
	@SearchableProperty(name="description")
	private String description;

	// Constructors

	/** default constructor */
	public Product() {
	}

	/** full constructor */
	public Product(String name, Double price, String brand, String description) {
		this.name = name;
		this.price = price;
		this.brand = brand;
		this.description = description;
	}

	// Property accessors

	public String getId() {
		return this.id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Double getPrice() {
		return this.price;
	}

	public void setPrice(Double price) {
		this.price = price;
	}

	public String getBrand() {
		return this.brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public String getDescription() {
		return this.description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

}

 

其中很多地方我还是不太明白。.....继续努力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值