Compass con Spring

De Dos Ideas.
Saltar a: navegación, buscar

Compass provee integración con Spring Framework a través de la clase LocalCompassBean, CompassDaoSupport y CompassTemplate

Introducción a Compass
Visitá el taller donde encontrarás más información, ejemplos y prácticas sobre este tema.

Clases principales

LocalCompassBean

Esta clase es similar al LocalSessionFactoryBean de Hibernate y permite configurar una instancia de Compass usando Spring. Esta instancia será luego inyectada a los diversos objetos que quieran acceder al índice (en particular, DAO que hereden de CompassDaoSupport).

CompassDaoSupport

Esta clase es similar a HibernateDaoSupport, y brinda métodos útiles para el uso de la session de Compass.

CompassTemplate

Esta clase es similar a HibernateTemplate, y provee métodos para usar la session de compass, y una gestión transparente de la transacción de Compass.

En particular, esta clase permite realizar varias operaciones dentro de una misma transacción a través de un CompassCallback.

Ejemplo

Entidad anotada para ser persistida en el índice mediante compass:

@Searchable public class EntidadIndexable implements Serializable {

   @SearchableId(name = "IdPadded", format = "0000000000", index = Index.ANALYZED, store = Store.YES)
   private Long id;
   @SearchableProperty(index = Index.ANALYZED, name = "msg")
   private String message;
   // Getters y setters.

}

Dao para guardar las entidades en el índice, utilizando la clase CompassTemplate:

public class IndexadorDaoImpl extends CompassDaoSupport implements IndexadorDao {

   public void indexar(final EntidadIndexable entidadIndexable) {
       getCompassTemplate().execute(new CompassCallback<EntidadIndexable>() {
           public EntidadIndexable doInCompass(CompassSession session) {
               session.save(entidadIndexable);
               return null;
           }
       });
   }
   public void indexar(final List<EntidadIndexable> entidadesAIndexar) {
       getCompassTemplate().execute(new CompassCallback<List<EntidadIndexable>>() {
           public List<EntidadIndexable> doInCompass(CompassSession session) {
               Iterator<EntidadIndexable> iterator = entidadesAIndexar.iterator();
               while (iterator.hasNext()) {
                   session.save(iterator.next());
               }
               return null;
           }
       });
   }

}

Es importante tener en cuenta que para manejar un gran volumen de datos deberíamos utilizar el método indexar que recibe por parámetro una lista. Esto se debe que al realizar el save dentro de la iteración de doInCompass se trabajará en una sola session y una sola transacción de compass para todas las entidades de la lista. De utilizar para cada elemento de la lista el método indexar que recibe por parámetro una entidad estaríamos abriendo y cerrando la session y la transacción para cada entidad, lo cual provoca que el tiempo de ejecución sea claramente mayor para guardar el mismo volumen de datos.


Factory para la construcción de compass:

public class CompassFactory implements FactoryBean {

   /**
    * nombreVariableEntorno que contiene la raiz del path del indice.
    */
   private String nombreVariableEntorno;
   /**
    * subDirectorio del indice.
    */
   private String subDirectorio;
   /**
    * Path del indice ($nombreVariableEntorno + subDirectorio).
    */
   private String pathIndice;
   
   /**
    * NO_EXISTE_VARIABLE_ENTORNO.
    */
   public static final String NO_EXISTE_VARIABLE_ENTORNO = "No existe la variable de entorno.";
   public void inicializar() {
       String path = System.getenv(getNombreVariableEntorno());
       if (Validador.esStringVacio(path)) {
           path = System.getProperty(getNombreVariableEntorno());
           if (Validador.esStringVacio(path)) {
               throw new DataAccessResourceFailureException(NO_EXISTE_VARIABLE_ENTORNO + "VariableEntorno:" + getNombreVariableEntorno());
           }
       }
       setPathIndice(path + getSubDirectorio());
   }
   public Object getObject() {
       CompassConfiguration conf = new CompassConfiguration().configure();
       conf.getSettings().setSetting(CompassEnvironment.CONNECTION, getPathIndice());
       conf.getSettings().setSetting(CompassEnvironment.CONNECTION_SUB_CONTEXT, "");
       return conf.buildCompass();
   }
   public Class getObjectType() {
       return Compass.class;
   }
   public boolean isSingleton() {
       return true;
   }
   
   // Getters y setters.

}

Configuración de spring:

   <bean id="dao.IndexadorDao" class="com.tm.prueba.dao.IndexadorDaoImpl">
       <property name="compass" ref="compass"/>
   </bean>
   <bean id="compass"
       class="com.tm.prueba.factory.CompassFactory" destroy-method="close" init-method="inicializar">
       <property name="nombreVariableEntorno" value="INDICE_PATH"/>
       <property name="subDirectorio" value="/indicePrueba/"/>
   </bean>

Ver también