2009年2月12日 星期四

How to generate Compass index when running unit test

Recently, I post a question to Appfuse mailling list entitle "Compass index not gen when running ActionTest"
Here is the packages I used in my project.

  • Compass 2.1.1
  • Lucene 2.4.0
  • Hibernate 3.3.0.ga
  • Appfuse 2.0.2
After 2 days hard works, luckily I found the solution to solve this problem. The exactly reason that Compass did not generate the index is caused by the Hibernate event not function properly when runing unit test.
Here is the setting in the hibernate.cfg.xml, this setting is used to let Compass can generate index automatically.

<event type="merge">
<listener class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
</event>
<event type="post-update">
<listener class="org.compass.gps.device.hibernate.embedded.CompassEventListener"/>
</event>
<event type="post-insert">
<listener class="org.compass.gps.device.hibernate.embedded.CompassEventListener"/>
</event>
<event type="post-delete">
<listener class="org.compass.gps.device.hibernate.embedded.CompassEventListener"/>
</event>

However, for some reason this configuration is not function as it designed under test environment. By the way, there are two hibernate.cfg.xml in Appfuse 2.0.2, one is located in src/main/resources, and the other is located in src/test/resources. In my project these two files are configured with same configuration.
The solution is quite easy, I remove the event handler setting and add the following code in my action.

product=(Product)mgr.save(product); //the manager.save will save the object to database

if(product.getObjid() != null)
compassTemplate.save(product); //using compassTemplate to generate the index manually.

Then the index can produce correctly in test environment.
I list my Compass configuration as following, in case someone need to setup their Compass.

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

<bean id="compass" class="org.compass.spring.LocalCompassBean">
<property name="classMappings">
<list>
<value>org.itri.istc.model.Product</value>
<value>org.itri.istc.model.Company</value>
</list>
</property>
<property name="compassConfiguration" ref="annotationConfiguration"/>
<property name="compassSettings">
<props>
<prop key="compass.engine.connection">file://d:/compass/imice</prop>
<prop key="compass.transaction.factory">org.compass.spring.transaction.SpringSyncTransactionFactory</prop>
<!-- snowball analyzer provides stemming (so 'monkey' gets 'monkeys', too) -->
<prop key="compass.engine.analyzer.default.type">snowball</prop>
<prop key="compass.engine.analyzer.default.name">English</prop>
<!--
<prop key="org.compass.core.lucene.LuceneEnvironment.Analyzer.ExtendedTypes">CHINESE</prop>
-->
<prop key="compass.property.all.enabled">true</prop>
<prop key="compass.transaction.lockTimeout">300</prop>
<prop key="compass.transaction.commitTimeout">300</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="nativeExtractor"><bean class="org.compass.spring.device.hibernate.SpringNativeHibernateExtractor" /></property>
</bean>
<bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps" init-method="start" destroy-method="stop">
<property name="compass"><ref bean="compass" /></property>
<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>


Reference:
1.http://chuanliang2007.spaces.live.com/blog/cns!E5B7AB2851A4C9D2!389.entry

沒有留言: